【问题标题】:Django count grouping by year/month without extraDjango按年/月分组计数,无需额外
【发布时间】:2016-02-12 17:03:36
【问题描述】:

我正在使用 django 1.9

型号:

class Comment(models.Model):
    title = models.CharField(max_length=250, null=False)
    date = models.DateField(auto_now_add=True)

由于 'extra()' 将在 django 中被弃用,我试图弄清楚如何在不使用 'extra' 的情况下按年计算评论组

这里是额外的代码:

Comment.objects.extra(select={'year': "EXTRACT(year FROM date)",
    'month': "EXTRACT(month from date)"})\
    .values('year', 'month').annotate(Count('pk'))

感谢您的帮助。

【问题讨论】:

  • 您可以在问题中添加您使用extra 的代码吗?
  • 好主意,我已将其添加到问题中。谢谢。
  • 使用RawSQL 可能是一个解决方案。

标签: python django aggregate annotate


【解决方案1】:

请参阅文档中的year and month,可能类似于以下内容可以完成这项工作:

Comment.objects.annotate(year=Q(date__year), 
                         month=Q(date__month)
                         ).values('year', 'month').annotate(Count('pk'))

如果这不起作用,那么您可以定义一个表示EXTRACT(year FROM date) 函数的自定义Func() 表达式,而不是Q(date__year),并在annotate() 中使用它。或者,作为最后的手段,有RawSQL()

使用Func(),类似这样:

from django.db.models import Func

class Extract(Func):
    """
    Performs extraction of `what_to_extract` from `*expressions`.

    Arguments:
        *expressions (string): Only single value is supported, should be field name to
                               extract from.
        what_to_extract (string): Extraction specificator.

    Returns:
        class: Func() expression class, representing 'EXTRACT(`what_to_extract` FROM `*expressions`)'.
    """

    function = 'EXTRACT'
    template = '%(function)s(%(what_to_extract)s FROM %(expressions)s)'


#Usage
Comment.objects.annotate(year=Extract(date, what_to_extract='year'), 
                             month=Extract(date, what_to_extract='month')
                             ).values('year', 'month').annotate(Count('pk'))

【讨论】:

  • 是的,我已经阅读了年月文档,并且我知道 date__year 是保留给 filtergetexclude 方法的字段查找。 doc。我无法通过您的 Func() 提案获得有效代码。我今天在挖。我可以用 rawSQL 解决这个问题,但我认为 extra() 的弃用是由于我们可以使用更好的 api 来处理所有 extra() 情况。
  • 是的,我在文档中看到了这一点,但是您是否尝试过将它们包裹在 Q 对象中。只是希望它会以某种方式解决。 =) 基本上使用Func(),您可以将 RawSQL 函数包装在可重用函数中以在 Django ORM 方法中使用。
  • @Ange Concerto,查看答案更新,在答案中为Func() 添加了一个 sn-p。
  • 不幸的是,如果您使用 Sqlite 作为数据库,这不起作用,因为它不支持 EXTRACT()
  • @PhilGyford SQLite 总体上有很多限制,所以在生产中你可能想要更强大的东西。其次,这整个问题与 SQLite 无关,因为 EXTRACT() 语句在问题本身中,如果我没记错的话,SQLite 不支持 datetime 类型。
猜你喜欢
  • 1970-01-01
  • 2017-03-25
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
  • 2017-09-23
  • 2021-01-16
  • 2016-04-02
  • 1970-01-01
相关资源
最近更新 更多