【问题标题】:Django queryset: Filter by reverse key and order byDjango查询集:按反向键过滤并排序
【发布时间】:2016-07-01 07:19:35
【问题描述】:

如何使用 procedurestatus_set 过滤最后一个 Status 在“1”中的 Procedure 模型。

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

在上面的例子中,我们可以得到Procedures Status (procedurestatus_set) 和 status 1,但不是最后一个 Status.status 为 1 的那些。

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

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

我正在使用 Django 1.9。

【问题讨论】:

  • 您这里没有状态日期,那么“最后”状态是什么?最大的主键?

标签: sql django postgresql django-queryset


【解决方案1】:

假设 'last' 表示最大的 pk,并且您想要查询最后一个 Status 具有 status==1 的所有 Procedure 实例,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 查询中需要的两个过滤器在实际访问数据库时不会合并到一个过滤器表达式中(django 会这样做),您必须将此嵌套表达式与id__in 一起使用。

在本例中,嵌套(内部)order_by 过滤器将Statusprocedure_id 分组并按pk 降序排列,distinct 选择第一个(最大的pk)@987654334 @ 对于每个 Procedure(注意:带有字段参数的 distinct 仅由带有一些 caveats 的 Postgres 支持)。然后,您可以将任何其他过滤器应用于外部 QuerySet。

Django ORM 应该将整体转换为对数据库的一个查询。

【讨论】:

  • 感谢 schwobaseggl,当使用这两个查询时,它就像一个魅力!
猜你喜欢
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-18
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 2018-09-26
相关资源
最近更新 更多