Django:如何订购查询集并将一些项目移动到查询集的末尾

Django: How to order a queryset and move some items to end of the queryset

我的 Django 应用程序中有一个查询集:

databytes_all = DataByte.objects

databytes_all 查询集中的每个项目都有许多属性,但其中之一是 publish_date

我想按 publish_date 对查询集进行排序,但是如果 publish_dateNone,我希望该项目位于查询集的末尾。

这是我正在尝试的方法,但它不起作用:

databytes_all = DataByte.objects

制作查询集:过滤掉所有 None

的发布日期
no_date = databytes_all.filter(publish_date=None)

创建另一个查询集:排除发布日期为 none 的所有项目,然后按发布日期

对剩余项目进行排序
databytes_with_date = databytes_all.order_by('-publish_date').exclude(publish_date=None)

现在组合两个查询集(但这不起作用 - 没有发布日期的项目在列表中排在第一位,而我希望它们排在最后)

databytes = databytes_with_date | no_date 

你不需要过滤,你可以指定NULL应该放在最后:

from django.db.models import F

databytes_all.order_by(F('publish_date')<b>.desc(nulls_last=True)</b>)

因此我们在这里使用 F object [Django-doc] where we call the .desc(…) method [Django-doc]。这个方法有一个 nulls_last=… 参数,我们可以用它来指定 NULL 的项目应该被选为最后的记录。

这将排序为:

SELECT …
FROM …
ORDER BY <b>publish_date IS NULL</b>, publish_date DESC

因为False/0被认为小于True/1,因此它会将带有publish_date的项目移动到底部您检索的记录。

在Django中,你可以使用chain组合很多QuerySet 试试这个:

from itertools import chain

...

combined_results = list(chain(databytes_with_date, no_date))