Django: 按日期分组(日、月、年)

22 浏览
0 Comments

Django: 按日期分组(日、月、年)

我有一个简单的模型,像这样:

class Order(models.Model):
    created = model.DateTimeField(auto_now_add=True)
    total = models.IntegerField() # monetary value

我想输出按月份分解的:

  • 每个月有多少销售量(COUNT
  • 合计价值(SUM

我不确定最好的方法是什么。我看过一些相当吓人的额外选择查询,但我简单的思路告诉我,我最好只是迭代数字,从一个任意的起始年/月开始,一直计数到当前月份,然后丢弃简单查询过滤该月份的数据。更多的数据库工作 - 开发者的压力更小!

对你来说最有意义的是什么?我能否以一种简便的方式返回一个快速的数据表?或者我的笨方法可能是最好的主意?

我正在使用Django 1.3。不确定他们最近是否添加了更好的GROUP_BY方法。

0
0 Comments

Django: Group by date (day, month, year)问题的出现原因是Django在1.10版本及以上中将extra方法标记为不久后将被弃用。为了解决这个问题,可以使用TruncMonth函数来进行分组。

在Django 1.10及以上版本中,可以使用以下代码来实现按月份分组:

from django.db.models.functions import TruncMonth
from django.db.models import Count
Sales.objects
    .annotate(month=TruncMonth('created'))  # Truncate to month and add to select list
    .values('month')                          # Group By month
    .annotate(c=Count('id'))                  # Select the count of the grouping
    .values('month', 'c')                     # (might be redundant, haven't tested) select month and count 

在旧版本的Django中,可以使用以下代码来实现按月份分组:

from django.db import connection
from django.db.models import Sum, Count
truncate_date = connection.ops.date_trunc_sql('month', 'created')
qs = Order.objects.extra({'month':truncate_date})
report = qs.values('month').annotate(Sum('total'), Count('pk')).order_by('month')

如果想要将日期转换为合适的datetime.date格式,可以使用xx.month.date()或者在模板中使用{{ row.month.date }}

需要注意的是,如果使用extra方法,要注意该方法可能会被弃用,应该尽量避免使用。在Django文档中有相关说明。

如果想要按照特定的日期间隔进行分组,比如按照7天进行分组,可以使用其他方法来实现。

另外,需要注意的是,如果Django的USE_TZ设置为True,使用TruncMonth函数和date_trunc_sql函数得到的结果可能不完全相同。TruncMonth函数会先将时间戳转换为TIME_ZONE设置指定的时区,然后再进行截断,而date_trunc_sql函数则是直接对数据库中的原始UTC时间戳进行截断。

以上是关于Django: Group by date (day, month, year)问题的原因以及解决方法的整理。

0
0 Comments

问题的出现原因是数据跨越多年时,使用ExtractMonth函数无法正确地按年份进行分组。因为每年的月份都是相同的,导致它们即使年份不同也会被分组在一起。

解决方法是使用ExtractYear函数来同时分组年份和月份。下面是使用ExtractYear和ExtractMonth函数的示例代码:

from django.db.models.functions import ExtractYear, ExtractMonth
Sales.objects
    .annotate(year=ExtractYear('timestamp'))
    .annotate(month=ExtractMonth('timestamp'))
    .values('year', 'month')
    .annotate(count=Count('id'))
    .values('year', 'month', 'count')

这样就可以按年份和月份同时进行分组,正确地统计每个月份的销售数量了。

0
0 Comments

Django: 按日期分组(天、月、年)

问题出现的原因:在使用Django 1.10.6和Postgres数据库时,按照月份分组的代码未能正常工作,需要添加order_by()方法才能解决。

解决方法:

1. 导入TruncMonth方法和Count方法:

from django.db.models.functions import TruncMonth

2. 使用annotate方法将时间戳字段按照月份截断并添加到select列表中:

Sales.objects
    .annotate(month=TruncMonth('timestamp'))

3. 使用values方法按照月份分组:

.values('month')

4. 使用annotate方法选择分组的计数:

.annotate(c=Count('id'))

5. 使用order_by方法对结果进行排序:

.order_by()

这样就能够按照日期(天、月、年)进行分组了。

参考文档:docs.djangoproject.com/en/1.11/topics/db/aggregation/…

一些用户评论:

- TruncDate可以按照日期(天)进行分组。

- 这个方法返回了我想要展示的准确输出。谢谢!

- .annotate(month=TruncMonth('timestamp'))中的timestamp是一个Python类型,这样命名有点混淆。

- Postgres数据库需要添加order_by才能正常工作,不知道为什么,但这就是问题所在。在文档上花了2个小时终于解决了。:( 谢谢。

- 我的数据库非常庞大,有几百万条记录。在实际应用中使用起来非常慢。有什么建议吗?

解决方法提供了按照日期进行分组的代码示例,并且指出了在使用Postgres数据库时需要注意的问题。对于需要对大型数据库进行操作的用户,可能需要优化数据库或者使用其他方法来提高性能。

0