django - reorder queryset after slicing it

﹥>﹥吖頭↗ 提交于 2019-12-21 04:34:32

问题


I fetch the latest 5 rows from a Foo model which is ordered by a datetime field.

qs = Foo.objects.all()[:5]

In the following step, I want to reorder the queryset by some other criteria (actually, by the same datetime field in the opposite direction). But reordering after a slice is not permitted. reverse() undoes the first ordering, giving me a differet queryset. Is there a way to accomplish what I want without creating a list from the queryset and doing the ordering using it?


回答1:


No, there's no way of doing that. order_by is an operation on the database, but when you slice a queryset it is evaluated and doesn't go back to the database after that.

Sounds like you already know the solution, though: run reversed() on the evaluated qs.

qs = reversed(Foo.objects.all()[:5])



回答2:


order_by gives you SQL in-database ordering. You're already using that, and then slicing on it. At that point, the results are retrieved into memory. If you want to change their order, you need to use Python in-memory sorting to do it, not the ORM in-database sorting.

In your case, Daniel has already given the best solution: since you simply want to sort by the same field, but in the other order, just reverse the list you have:

qs = Foo.objects.all()[:5]
objs = reversed(qs)

If you had wanted to sort by some other field, then you'd use the sorted() function with a custom key function:

qs = Foo.objects.all()[:5]
objs = sorted(qs, key=lambda o: o.some_other_field)



回答3:


Late answer, but this just worked for me:

import random
sorted(queryset[:10], key=lambda x: random.random())


来源:https://stackoverflow.com/questions/939035/django-reorder-queryset-after-slicing-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!