django按不同字段的最新日期排序查询集

时间:2018-04-26 14:12:06

标签: python django

如何像论坛一样对查询集进行排序?

我的意思是按一个日期字段排序,并且会有另一个订单日期 用于排序,例如在论坛中:主题按创建日期(或更新日期)排序,但如果任何旧主题得到新回复,则在其他主题之前将显示。这正是我试图做的事情。

到目前为止我尝试了什么:

    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"是另一个模型,由外键连接。

1 个答案:

答案 0 :(得分:3)

如果我说得对,您可以使用annotationsdatabase functions来实现这一目标。

一次一件事。

  1. 您希望按降序顺序按回复日期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')
    
  2. 现在,所有主题至少有一个回复排序,但主题没有回复呢?

    我们可以像这样重新排序:“如果有回复则按上次回复日期排序,按最后一次主题更新”。

    “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')