我有两个模型,一个项目和一个动作:
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)
我需要一个返回所有没有状态<的操作的项目的查询2。
我试过了:
Project.objects.filter(action__status__gt = 1)
但是这会返回所有项目,因为在每个项目中,有一些状态为2的操作和一些状态小于2的操作。此外,它在结果查询中重复了Projects。我目前的解决方案如下:
Project.objects.filter(action__status__gt =1).exclude(action__status__lt =2).annotate()
这会折叠重复结果并仅显示操作状态大于1的操作。但这是构建此类查询的正确方法吗?如果我想返回动作状态大于1的项目或没有动作的项目,该怎么办?
答案 0 :(得分:0)
Django的ORM无法表达这一点。您需要使用原始查询才能执行此操作。
答案 1 :(得分:0)
我可能误解了你的要求,但我认为你可以使用注释来做到这一点。
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
)
这是不言自明的。