여기에 빠른 것이 있습니다.
QuerySet (또는 필요한 경우 배열)을 반환하는 데 사용하려는 ID 목록이 있지만 그 순서를 유지하고 싶습니다.
감사
답변:
나는 당신이 데이터베이스 수준에서 특정 순서를 강요 할 수 없다고 생각하기 때문에 대신 파이썬으로해야한다.
id_list = [1, 5, 7]
objects = Foo.objects.filter(id__in=id_list)
objects = dict([(obj.id, obj) for obj in objects])
sorted_objects = [objects[id] for id in id_list]
이렇게하면 ID를 키로 사용하여 개체의 사전이 만들어 지므로 정렬 된 목록을 만들 때 쉽게 검색 할 수 있습니다.
Django 1.8부터 다음을 수행 할 수 있습니다.
from django.db.models import Case, When
pk_list = [10, 2, 1]
preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)])
queryset = MyModel.objects.filter(pk__in=pk_list).order_by(preserved)
Case
When
가 과소 평가 되었다고 생각합니다 !
distinct()
order_by case when 절과 함께 사용 하지만 오류가 발생했습니다. 어떤 지원을 부탁드립니다.
SELECT DISTINCT ON expressions must match initial ORDER BY expressions
-여기에 오류 메시지가 있습니다
다음은 데이터베이스 수준에서 수행하는 방법입니다. 다음에서 붙여 넣기 복사 : blog.mathieu-leplatre.info :
MySQL :
SELECT *
FROM theme
ORDER BY FIELD(`id`, 10, 2, 1);
Django와 동일 :
pk_list = [10, 2, 1]
ordering = 'FIELD(`id`, %s)' % ','.join(str(id) for id in pk_list)
queryset = Theme.objects.filter(pk__in=[pk_list]).extra(
select={'ordering': ordering}, order_by=('ordering',))
PostgreSQL :
SELECT *
FROM theme
ORDER BY
CASE
WHEN id=10 THEN 0
WHEN id=2 THEN 1
WHEN id=1 THEN 2
END;
Django와 동일 :
pk_list = [10, 2, 1]
clauses = ' '.join(['WHEN id=%s THEN %s' % (pk, i) for i, pk in enumerate(pk_list)])
ordering = 'CASE %s END' % clauses
queryset = Theme.objects.filter(pk__in=pk_list).extra(
select={'ordering': ordering}, order_by=('ordering',))
id_list = [1, 5, 7]
objects = Foo.objects.filter(id__in=id_list)
sorted(objects, key=lambda i: id_list.index(i.pk))