#32685 closed New feature (wontfix)
Add feature to preserve order in .filter(field__in=list) query
| Reported by: | Barney Szabolcs | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 2.2 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
filter __in query does not guarantee to preserve order, so I usually sort afterwards using python's sort.
However, in django admin I cannot sort queries using python's sort when manipulating the QuerySet
since I have to return a QuerySet.
So, I'd do something like
queryset.filter(my_field__in=my_values).raw(
f'order by array_position(ARRAY[{ ",".join(["%s"]*len(my_values)) }]::varchar[], my_field)',
params=my_values)
but this does not work...
is there a solution here? (I cannot use raw either since I have a queryset input argument to work with)
UPDATE:
now, I've found a cryptic solution:
https://stackoverflow.com/a/37648265/1031191
from django.db.models import Case, When preserved = Case(*[When(my_field=val, then=pos) for pos, val in enumerate(my_values)], default=len(my_values)) queryset.filter(my_field__in=my_values).order_by(preserved)
I think Django should provide a better way than this.
Maybe queryset.filter(my_field__in_preserve=my_values)
Change History (3)
comment:1 by , 5 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 5 years ago
| Component: | Uncategorized → Database layer (models, ORM) |
|---|---|
| Resolution: | → wontfix |
| Status: | new → closed |
| Type: | Uncategorized → New feature |
comment:3 by , 5 years ago
| Description: | modified (diff) |
|---|
This behavior depends on a database, it has nothing to do with Django itself. If you want to preserve the ordering from the
INclause you can useCaseor split your queryset into multiple combined queries. IMO neither of these workarounds should be built-in into Django, they are a bit hacky and quite niche.