oto szybki dla ciebie:
Mam listę identyfikatorów, których chcę użyć, aby zwrócić QuerySet (lub tablicę, jeśli trzeba), ale chcę zachować tę kolejność.
Dzięki
Nie sądzę, abyś mógł wymusić tę konkretną kolejność na poziomie bazy danych, więc zamiast tego musisz to zrobić w Pythonie.
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]
Tworzy to słownik obiektów z ich identyfikatorem jako kluczem, dzięki czemu można je łatwo odzyskać podczas tworzenia posortowanej listy.
Od Django 1.8 możesz:
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)
źródło
Case
When
są niedoceniane!distinct()
z klauzulą order_by, gdy wystąpił błąd. jakieś wsparcie, proszę.SELECT DISTINCT ON expressions must match initial ORDER BY expressions
- tutaj jest komunikat o błędzieJeśli chcesz to zrobić za pomocą in_bulk, w rzeczywistości musisz połączyć dwie powyższe odpowiedzi:
id_list = [1, 5, 7] objects = Foo.objects.in_bulk(id_list) sorted_objects = [objects[id] for id in id_list]
W przeciwnym razie wynikiem będzie słownik, a nie specjalnie uporządkowana lista.
źródło
Oto sposób na zrobienie tego na poziomie bazy danych. Skopiuj wklej z: blog.mathieu-leplatre.info :
MySQL :
SELECT * FROM theme ORDER BY FIELD(`id`, 10, 2, 1);
To samo z 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;
To samo z 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',))
źródło
id_list = [1, 5, 7] objects = Foo.objects.filter(id__in=id_list) sorted(objects, key=lambda i: id_list.index(i.pk))
źródło