过滤Django注释的现代方法?

时间:2015-09-14 02:31:25

标签: django django-models orm

我想使用Django ORM过滤注释。我在SO上发现的很多文章都相当过时,在1.2到1.4天内将Django定为目标:

Django 1.8添加conditional aggregation,这似乎是我想要的,但我无法弄清楚我最终需要的语法。这是我的模型和我想要达到的场景(为简洁起见我简化了模型):

class Project(models.Model):
    name = models.CharField()
    ... snip ...

class Milestone_meta(models.Model):
    name = models.CharField()
    is_cycle = models.BooleanField()

class Milestone(models.Model):
    project = models.ForeignKey('Project')
    meta = models.ForeignKey('Milestone_meta')
    entry_date = models.DateField()

我希望每个Project(包含其所有字段)以及每个关联Max(entry_date)的{​​{1}}和Min(entry_date),但仅限{{1}其关联的MilestoneMilestone标志设置为True的记录。换句话说:

  • 对于每个项目记录,给我最大和最小Milestone entry_dates,但仅限于关联的Milestone_meta将给定标志设置为True时。

目前,我正在获取一个项目列表,然后将Milestone_metais_cycle里程碑置于一个循环中,导致N + 1个数据库命中(这会慢,因为你' d expect):

Max

如何将此减少为一个或两个查询?

1 个答案:

答案 0 :(得分:0)

据我所知,您无法在一个查询中获取所有必需的project个对象。

但是,如果你不需要这些对象并且只能使用它们的id,那么一种方法就是 -

Milestone.objects.filter(meta__is_cycle=True).values('project').annotate(min_entry=Min('entry_date')).annotate(max_entry=Max('entry_date'))

它将给出一个包含不同项目数据的词典列表,然后您可以使用它们的“id”在需要时查找对象。