order_by on Many-to-Many字段导致queryset中出现重复条目

时间:2014-05-12 02:45:25

标签: django postgresql django-queryset django-orm django-postgresql

我正在尝试执行基于m2m字段的order_by,但它最终会在我的查询集中创建重复的条目。我一直在搜索关于堆栈交换的django文档和相关问题,但我还没有能够提出任何解决方案。

型号:

class WorkOrder(models.Model):
    ...
    appointment = models.ManyToManyField(Appointment, null=True, blank=True, related_name = 'appointment_from_schedule')
    ...

class Appointment(models.Model):

    title = models.CharField(max_length=1000, blank=True)
    allDay = models.BooleanField(default=False)
    start = models.DateTimeField()
    end = models.DateTimeField(null=True, blank=True)
    url = models.URLField(blank=True, null=True)

查询:

qs = WorkOrder.objects.filter(work_order_status="complete").order_by("-appointment__start")

结果:

[<WorkOrder: 45: Davis>, <WorkOrder: 45: Davis>]

在互动模式下:

>>>qs[0] == a[1]
True
>>>qs[0].pk
45
>>>qs[1].pk
45

如果我删除了order_by,那么我只得到一个结果,但稍后添加它会将重复的条目放回去。

>>>qs = WorkOrder.objects.filter(work_order_status="complete")
>>>qs
[<WorkOrder: 45: Davis>]
>>>qs.order_by('appointment__start')
[<WorkOrder: 45: Davis>, <WorkOrder: 45: Davis>]

我尝试添加.distinct()和.distinct(&#39; pk&#39;),但前者没有效果,后者导致错误:

ProgrammingError: SELECT DISTINCT ON expressions must match initial ORDER BY expressions

2 个答案:

答案 0 :(得分:1)

您可以尝试将annotatevalues

一起使用
qs = WorkOrder.objects.filter(work_order_status="complete").values("appointment").annotate(status="work_order_status").order_by("-appointment__start")

答案 1 :(得分:1)

我接受了sfletche提供的关于使用注释的建议,并在freenode.net irc频道#django中讨论了这个问题。

用户FunkyBob和jtiai能够帮助我实现它。

由于每个工单可以有多个约会,当我们要求它按约会订购时,它会为每个约会实例返回一行,因为它不知道我打算订购哪个约会。

from django.db.models import Max

WorkOrder.objects.annotate(max_date=Max('appointment__start')).filter(work_order_status="complete").order_by('max_date')

所以,我们走的正确道路就是让语法正确。

感谢您帮助sfletche,FunkyBob和jtiai。