如何像论坛一样对查询集进行排序?
我的意思是按一个日期字段排序,并且会有另一个订单日期 用于排序,例如在论坛中:主题按创建日期(或更新日期)排序,但如果任何旧主题得到新回复,则在其他主题之前将显示。这正是我试图做的事情。
到目前为止我尝试了什么:
subjects = Subjects.objects.filter(active=True).order_by('-sticky', '-updated_date', 'reply__updated_date')
但在这种情况下,结果将作为回复计数重复。
我也尝试过:
subjects = Subjects.objects.filter(active=True).order_by('-sticky', '-updated_date').order_by('reply__updated_date')
但在这种情况下,第二个order_by
会覆盖第一个Subject
。
有没有可以遵循的准则?
顺便说一句,我很确定你得到了它,但为了清楚起见,Reply
是一个模型而android:extractNativeLibs="false"
是另一个模型,由外键连接。
答案 0 :(得分:3)
如果我说得对,您可以使用annotations和database functions来实现这一目标。
一次一件事。
您希望按降序顺序按回复日期对Subjects
进行排序:在Django自己的条款中,您需要annotate()
每个Subjects
使用其相关模型updated_date
的最大reply
,并按相反的顺序按新字段排序Subjects
,如下所示:
from django.db.models import Max
subjects = Subject.objects.annotate(lr=Max('reply__updated_date'))\
.order_by('-lr')
现在,所有主题至少有一个回复排序,但主题没有回复呢?
我们可以像这样重新排序:“如果有回复则按上次回复日期排序,按最后一次主题更新”。
“else”部分可以通过Coalesce()函数实现,该函数用我们选择的另一个表达式替换NULL。在我们的例子中,它将使用主题<{strong>的updated_date
字段替换Max()内部的内容:
from django.db.models import Max
from django.db.models.functions import Coalesce
subjects = Subject.objects\
.annotate(lr=Coalesce(Max('reply__updated_date'), 'updated_date'))\
.order_by('-lr')