django注释计数过滤器

时间:2012-02-16 12:20:24

标签: django django-queryset annotate

我正在尝试计算某些模型的每日记录,但我希望计数仅针对具有一些fk field = xy的记录,因此我得到列表,其中有创建新记录但有些可能返回0的日期。

class SomeModel(models.Model):
    place = models.ForeignKey(Place)
    note = models.TextField()
    time_added = models.DateTimeField()

说有一个名为=“NewYork”的地方

data = SomeModel.objects.extra({'created': "date(time_added)"}).values('created').annotate(placed_in_ny_count=Count('id'))

这有效,但显示所有记录..所有地方。

尝试过滤,但它没有返回天数,其中没有place.name="NewYork"的记录。那不是我需要的。

1 个答案:

答案 0 :(得分:1)

看起来您想知道,对于添加任何对象的每一天,当天创建的对象中有多少个名称为纽约的地方。 (如果我误解了,请告诉我。)在SQL中需要outer join

SELECT m.id, date(m.time_added) AS created, count(p.id) AS count
  FROM myapp_somemodel AS m
  LEFT OUTER JOIN myapp_place AS p
       ON m.place_id = p.id
       AND p.name = 'New York'
  GROUP BY created

所以你总是可以使用raw SQL query

在Django中表达这一点
for o in SomeModel.objects.raw('SELECT ...'):   # query as above
    print 'On {0}, {1} objects were added in New York'.format(o.created, o.count)

注意:

  1. 如果在Django的查询语言中可以表达,我还没有尝试过。它可能是,但as the developers say,数据库API是“捷径,但不一定是最终的全部。”

  2. m.id在SQL查询中是多余的,但Django requires表示“主键...必须始终包含在原始查询中”。

  3. 您可能不希望将文字'New York'写入您的查询,因此pass a parameter代替:raw('SELECT ... AND p.name = %s ...', [placename])