【问题标题】:Django postgres order_by distinct on fieldDjango postgres order_by 在字段上不同
【发布时间】:2017-06-09 13:34:28
【问题描述】:

我们对 order_by/distinct 字段有限制。 来自docs:“order_by()中的字段必须以distinct()中的字段开头,顺序相同”

现在是用例:

class Course(models.Model):
    is_vip = models.BooleanField()
    ...

class CourseEvent(models.Model):
    date = models.DateTimeField()
    course = models.ForeignKey(Course)

目标是获取课程,按最近的日期排序,但 vip 优先。

解决方案可能如下所示:

CourseEvent.objects.order_by('-course__is_vip', '-date',).distinct('course_id',).values_list('course')

但由于限制,它会导致错误。

是的,我明白为什么在使用 distinct 时需要排序 - 我们为 course_id 的每个值获取第一行,因此如果我们不指定顺序,我们会得到一些任意行。 但是将顺序限制在我们不同的同一领域的目的是什么?

如果我将 order_by 更改为 ('course_id', '-course__is_vip', 'date',) 它会给我一行课程,但课程的顺序与目标没有任何共同之处。

除了遍历整个查询集并循环过滤之外,还有什么方法可以绕过这个限制?

【问题讨论】:

    标签: python django postgresql


    【解决方案1】:

    您可以使用id__in 进行嵌套查询。在内部查询中,您可以挑选出不同的事件,在外部查询中,您可以自定义它们:

    CourseEvent.objects.filter(
        id__in=CourseEvent.objects\
            .order_by('course_id', '-date').distinct('course_id')
    ).order_by('-course__is_vip', '-date')
    

    来自distinct(*fields) 上的文档:

    指定字段名时,必须在QuerySet中提供order_by(),order_by()中的字段必须以distinct()中的字段开头,顺序相同。

    【讨论】:

    • 不,这会给我按课程 ID 排序的课程,而不是按最近的日期和 vip 标志。
    • 第二个 order_by 也无济于事,因为我们已经通过进行不同的调用而丢失了有关日期的信息
    • 不,你没有。没有第二个order_by。您拥有每个 course_id 的所有最新记录。每个嵌套查询中都有一个 order 子句
    • 是的,但是 .order_by('course_id', '-course__is_vip', '-date') 与 .order_by('course_id',) 完全一样,因为 id 是唯一的。所以我们从来没有这个信息
    • 不,id 对于CourseEvent 是唯一的,course_id 不是!多个事件可以指向同一个课程。我承认,course__is_vip 是多余的。已更新,已删除外order_by中的错误项目
    猜你喜欢
    • 2014-06-20
    • 2017-11-24
    • 2011-03-10
    • 2016-05-15
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    • 2019-06-04
    • 2016-06-18
    相关资源
    最近更新 更多