Keeping order with order_by while using id__in

24 views
Skip to first unread message

Raisins

unread,
Dec 21, 2008, 11:58:33 AM12/21/08
to Django users
i = [ 1, 5,2,6]
Model.objects.filter(id__in = i)

This currently will order them by id, even if i call order_by() with
no parameters. The docs say "If you don't want any ordering to be
applied to a query, not even the default ordering, call order_by()
with no parameters."

Is there a way to maintain the order I have in the list?

Malcolm Tredinnick

unread,
Dec 21, 2008, 8:16:13 PM12/21/08
to django...@googlegroups.com
There is no ordering going on here. The results are coming back in
whatever (arbitrary) order they are stored in the database, which is
often the order in which they were inserted (although not always,
particularly with PostgreSQL). The database doesn't pull out the results
one at a time in the order you specify them. It finds the intersection
between your list of values and those that are available as rows in the
database and does no further sorting (SQL is primarily set operations,
after all).

I'm only going into all that detail so that you can see what's really
going on here. The point being that there's no ordering at all going on.

There isn't any way with Django's ORM (or standard SQL -- although, from
memory, some databases have extensions that might allow this) to specify
the ordering you're after here. However, it's not too hard to do this in
Python. Here's one (untested, but it should be close) approach:

id_list = [1, 5, 2, 6]
qs = Model.objects.filter(id__in=id_list)
index = dict([(id, pos) for (pos, id) in enumerate(id_list)])
result = [None] * len(id_list)
for obj in qs:
result[index[obj.id]] = obj

The "result" list will be the sorted results. There are some alternative
approaches as well, but that should give you a starting point.

Regards,
Malcolm



> >
>

Raisins

unread,
Dec 22, 2008, 2:46:47 AM12/22/08
to Django users
Thanks for the in depth feedback about what is going on with the
order.

Also thanks for the code snippet. I ended up doing something very
similar.

On Dec 21, 8:16 pm, Malcolm Tredinnick <malc...@pointy-stick.com>
wrote:
Reply all
Reply to author
Forward
0 new messages