django - 切片后重新排序查询集

发布于 2024-07-22 07:39:20 字数 242 浏览 6 评论 0原文

我从 Foo 模型中获取最新 5 行,该模型按日期时间字段排序。

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

在接下来的步骤中,我想通过其他一些条件(实际上,通过相反方向的相同日期时间字段)对查询集重新排序。 但不允许在切片后重新排序。 reverse() 撤消第一个排序,给我一个不同的查询集。 有没有一种方法可以完成我想要的任务,而无需从查询集中创建列表并使用它进行排序?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温馨耳语 2024-07-29 07:39:20

order_by 为您提供 SQL 数据库内排序。 你已经在使用它了,然后对其进行切片。 此时,结果将被检索到内存中。 如果你想改变它们的顺序,你需要使用Python内存排序来完成,而不是ORM数据库排序。

在你的情况下,丹尼尔已经给出了最好的解决方案:因为你只是想按相同的字段排序,但以其他顺序排序,只需颠倒你的列表:

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

如果你想按其他字段排序,那么你' d 将sorted()函数与自定义键函数一起使用:

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

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)
笨死的猪 2024-07-29 07:39:20

不,没有办法这样做。 order_by 是对数据库的操作,但是当您对查询集进行切片时,它会被评估并且之后不会返回到数据库。

不过,听起来您已经知道解决方案了:在评估的 qs 上运行 reversed()

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

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])
像极了他 2024-07-29 07:39:20

迟到的回答,但这对我有用:

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

Late answer, but this just worked for me:

import random
sorted(queryset[:10], key=lambda x: random.random())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文