MiddleКодИногдаЕщё не отвечали
Упорядочить Django queryset по произвольному списку id в памяти
У вас есть список id в определённом порядке. Верните queryset, строки которого выходят именно в этом порядке — не по значению id, а по позиции в списке.
Требования:
- упорядочивание должно делать база (без пересортировки в Python после запроса)
from django.db.models import Case, When
ids = [5, 10, 2, 4, 9, 1]
def ordered(ids: list):
# ваш код здесь
...
Допишите реализацию.
Аннотируйте каждую строку её позицией в списке через Case/When, затем упорядочьте по этой аннотации: preserved = Case(*[When(id=pk, then=pos) for pos, pk in enumerate(ids)]), затем MyModel.objects.filter(pk__in=ids).annotate(_order=preserved).order_by('_order'). База вычисляет выражение CASE для каждой строки, поэтому нужный порядок формируется в SQL, а не пересортировкой в Python.
- ✗Считать, что
pk__inсохраняет порядок списка id - ✗Пересортировывать в Python вместо того, чтобы это делал SQL
- ✗Упорядочивать по
id, считая, что это совпадёт с произвольным порядком
- →Почему
pk__inне гарантирует порядок своего списка-аргумента? - →Как выражение
CASEсопоставляет каждый id его позиции?