51

我有一个类似于以下的模型:

class Review(models.Model):
    venue = models.ForeignKey(Venue, db_index=True)
    review = models.TextField()  
    datetime_created = models.DateTimeField(default=datetime.now)

我想查询数据库以获取按天分组的场所的评论总数。MySQL 查询将是:

SELECT DATE(datetime_created), count(id) 
FROM REVIEW 
WHERE venue_id = 2
GROUP BY DATE(datetime_created);

在 Django 中完成此任务的最佳方法是什么?我可以用

Review.objects.filter(venue__pk=2)

并解析视图中的结果,但这对我来说似乎不正确。

4

5 回答 5

95

这应该可以工作(使用您使用的相同的 MySQL 特定函数):

Review.objects.filter(venue__pk=2)
    .extra({'date_created' : "date(datetime_created)"})
    .values('date_created')
    .annotate(created_count=Count('id'))
于 2010-02-17T19:51:30.057 回答
23

现在Extra()正在贬值,一个更合适的答案将使用Trunc例如这个接受的答案

现在OP的问题将回答如下

from django.db.models.functions import TruncDay

Review.objects.all()
    .annotate(date=TruncDay('datetime_created'))
    .values("date")
    .annotate(created_count=Count('id'))
    .order_by("-date")
于 2017-01-30T07:34:38.673 回答
17

为了完整起见,由于 extra() 旨在弃用,因此可以使用这种方法:

from django.db.models.expressions import DateTime

Review.objects.all().\
    annotate(month=DateTime("timestamp", "month", pytz.timezone("Etc/UTC"))).\
    values("month").\
    annotate(created_count=Count('id')).\
    order_by("-month")

它在 django 1.8 中对我有用,在 sqlite 和 MySql 数据库中都是如此。

于 2015-12-24T19:25:57.520 回答
13

如果您要存储日期字段,则可以使用:

from django.db.models import Count

Review.objects.filter(venue__pk = 2)
    .values('date').annotate(event_count = Count('id'))

因为您要存储日期时间,所以它有点复杂,但这应该提供一个很好的起点。在此处查看聚合文档。

于 2010-02-17T18:32:57.057 回答
3

您还可以定义自定义函数:

from django.db.models.expressions import Func

# create custom sql function
class ExtractDateFunction(Func):
    function = "DATE" # thats the name of function, the way it mapped to sql

# pass this function to annotate
Review.objects.filter(venue__pk=2)
      .annotate(date_created=ExtractDateFunction("datetime_created"))
      .values('date_created')
      .annotate(created_count=Count('id'))

只需确保您的数据库引擎支持 DATE 功能

于 2016-04-11T05:50:23.587 回答