【问题标题】:Django query based on foreign key relationship基于外键关系的Django查询
【发布时间】:2012-10-10 23:37:00
【问题描述】:

我有两个模型,一个项目和一个动作:

class Project(models.Model):
    name = models.CharField("Project Name", max_length=200, unique = True)

class Action(models.Model):
    name = models.CharField("Action Name", max_length=200)
    project = models.ForeignKey(Project, blank=True, null=True, verbose_name="Project")
    notes = models.TextField("Notes", blank=True)
    complete = models.BooleanField(default=False, verbose_name="Complete?")
    status = models.IntegerField("Action Status", choices = STATUS, default=0)

我需要一个查询来返回所有没有状态为

我试过了:

Project.objects.filter(action__status__gt = 1)

但这会返回所有项目,因为在每个项目中,都有一些状态为 2 的操作和一些状态小于 2 的操作。此外,它在结果查询中重复了项目。我目前的解决方案如下:

Project.objects.filter(action__status__gt =1).exclude(action__status__lt =2).annotate()

这会折叠重复的结果并仅显示动作状态大于 1 的动作。但这是构造此类查询的正确方法吗?如果我想返回操作状态大于 1 的项目或没有操作的项目怎么办?

【问题讨论】:

    标签: mysql django django-queryset


    【解决方案1】:

    我可能误解了您的要求,但我认为您可以使用注释来做到这一点。

    Project.objects.annotate(m = Min('action__status')).filter(Q(m = None) | Q(m__gt = 1))

    生成的SQL是:

    SELECT
        "testapp_project"."id", "testapp_project"."name", 
        MIN("testapp_action"."status") AS "m" 
    FROM "testapp_project" 
    LEFT OUTER JOIN "testapp_action" ON ("testapp_project"."id" = "testapp_action"."project_id") 
    GROUP BY "testapp_project"."id", "testapp_project"."name" 
    HAVING(
           MIN("testapp_action"."status") IS NULL 
        OR MIN("testapp_action"."status") > 1 
    )
    

    这是不言自明的。

    【讨论】:

      【解决方案2】:

      Django 的 ORM 无法表达这一点。您需要使用原始查询来执行此操作。

      【讨论】:

      • 谢谢。我明白为什么这可能是真的。对于如何构建这个原始查询有什么建议吗?
      猜你喜欢
      • 2020-01-02
      • 1970-01-01
      • 2015-07-30
      • 2014-07-22
      • 2020-04-20
      • 1970-01-01
      • 1970-01-01
      • 2018-12-14
      • 2010-09-10
      相关资源
      最近更新 更多