MiddleCodeOccasionalNot answered yet
Order a Django queryset by an arbitrary in-memory id list
You have a list of ids in a specific order. Return a queryset whose rows come out in exactly that order — not by id value, but by the position in the list.
Requirements:
- the database must do the ordering (no Python re-sorting after the query)
from django.db.models import Case, When
ids = [5, 10, 2, 4, 9, 1]
def ordered(ids: list):
# your code here
...
Write the implementation.
Annotate each row with its position in the list using Case/When, then order by that annotation: preserved = Case(*[When(id=pk, then=pos) for pos, pk in enumerate(ids)]), then MyModel.objects.filter(pk__in=ids).annotate(_order=preserved).order_by('_order'). The database evaluates the CASE expression per row, so the requested order is produced in SQL, not re-sorted in Python.
- ✗Assuming
pk__inpreserves the order of the id list - ✗Re-sorting in Python instead of letting SQL do it
- ✗Ordering by
idand assuming it matches the custom order
- →Why does
pk__innot guarantee the order of its argument list? - →How does the
CASEexpression map each id to its position?