Django queryset:按反向键过滤并按顺序排序

时间:2016-03-15 17:34:36

标签: sql django postgresql django-queryset

如何过滤Procedure的最后Status个' 1'使用procedurestatus_set

class Procedure(models.Model):
    name = models.CharField(
        max_length=256,
    )

Class Status(models.Model)
    procedure = models.ForeignKey(
       Procedure,
    ) 

    status = models.CharField(
        max_length=256,
    )

Procedure.objects.filter(status__status='1')

在上面的示例中,我们可以获得具有任何内容的Procedure Status procedurestatus_set)与status 1,但不是Status.status为1的人。

如何通过验证他们的最后Procedure来过滤Status

Procedure.objects.filter(status__last__status='1')

我正在使用Django 1.9。

1 个答案:

答案 0 :(得分:1)

假设'last'表示最大的pk,并且您想要查询最后Procedure具有Status的所有status==1个实例,postgres允许您进行以下操作:

last_statuses=Status.objects.filter(
    id__in=Status.objects.order_by('procedure_id', '-pk').distinct('procedure_id')
).filter(status=1)

procedures = Procedure.objects.filter(id__in=last_statuses.values('procedure_id'))

为了使Status查询中需要的两个过滤器在实际访问db时(django将执行)不要合并到一个过滤器表达式中,您必须使用此嵌套表达式{id__in 1}}。

在目前的情况下,order_by的嵌套(内部)Status过滤器组procedure_id并按降序pk对其进行排序,distinct选择每个pk的第一个(最大StatusProcedure(注意:带有字段参数的distinct仅由Postgres支持caveats}。然后,您可以将任何其他过滤器应用于外部QuerySet。

Django ORM应该将整个翻译成一个查询到数据库。