【补充】根据年月对文章进行分组
【一】官方文档的参考写法
Django官网提供的 orm 语法
# django官网提供的一个orm语法
from django.db.models.functions import TruncMonth
-官方提供
from django.db.models.functions import TruncMonth
Sales.objects
.annotate(month=TruncMonth('timestamp')) # 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 countSales就是指models里面的模型类
-
from django.db.models.functions import TruncMonth
:导入TruncMonth
函数,该函数用于将日期时间字段截断到月份,并将其添加到选择列表中。 -
Sales.objects
:Sales
是一个模型类,通过使用objects
属性可以获取该模型类对应的查询集对象,可以对其进行查询和操作。 -
annotate(month=TruncMonth('timestamp'))
:使用annotate
方法扩展查询集,在结果中添加一个名为month
的字段,并使用TruncMonth
函数对timestamp
字段进行截断。 -
.values('month')
:将结果按照month
字段进行分组。 -
.annotate(c=Count('id'))
:对分组后的结果再次使用annotate
方法,在结果中添加一个名为c
的字段,该字段表示每个分组中id
字段的计数。 -
.values('month', 'c')
:指定返回结果中的字段,包括month
和c
字段。
【二】简单的示例
# 按照年月统计所有的文章
date_list = models.Article.objects.filter(blog=blog).annotate(month=TruncMonth('create_time')).values("month").annotate(count_num=Count("pk")).values_list('month','count_num')
# 先filter(blog=blog)查找到当前用户的所有文章
# annotate(month=TruncMonth('create_time')) 以创建时间的月分组
# 第二个annotate前的values("month")是分组条件
【三】我的项目中的演示
year, month = param.split('-') # 2023-06 > [2023,06]
article_list = article_list.filter(create_time__year=year, create_time__month=month)
【四】扩展
【Trunc】
Trunc
:- 这是一个用于日期时间字段截断的函数类。
- 它可以用于按照指定的单位(如年、月、周等)来截断日期时间字段。
Trunc
函数可以根据具体需求选择不同的截断单位- 例如
TruncYear
(按年截断) TruncMonth
(按月截断)TruncDay
(按天截断)等。
- 例如
【Extract】
Extract
:- 这个函数类用于从日期时间字段中提取指定部分(如年、月、日等)。
- 可以使用具体的
Extract
函数- 如
ExtractYear
(提取年份) ExtractMonth
(提取月份)ExtractDay
(提取天数)等。
- 如
【1】TruncMonth
- 当使用
TruncMonth
函数时- 它可以用于按照月份截断日期时间字段。
- 下面是一个使用
TruncMonth
函数的示例:
- 假设我们有一个模型类
Transaction
- 其中包含一个
date
字段,表示交易发生的日期。
- 其中包含一个
- 我们可以使用
TruncMonth
函数来按月份截断日期- 并计算每个月的交易总额。
from django.db.models import Sum
from django.db.models.functions import TruncMonth
from myapp.models import Transaction
# 查询每个月的交易总额
monthly_totals = Transaction.objects.annotate(
month=TruncMonth('date')
).values('month').annotate(
total_amount=Sum('amount')
).order_by('month')
for entry in monthly_totals:
month = entry['month']
total_amount = entry['total_amount']
print(f"{month.strftime('%Y-%m')}: {total_amount}")
- 在上面的示例中,首先使用
annotate
方法和TruncMonth('date')
来创建一个新的字段month
- 该字段对应于每个交易的月份。
- 然后使用
values
和annotate
来分组并计算每个月的交易总额。 - 最后使用
order_by
对结果进行排序。
【2】TruncYear
-
TruncYear
是Django ORM中的一个函数- 用于按照年份截断日期时间字段。
- 下面是对
TruncYear
函数的详细解释和使用案例:
-
TruncYear
函数可以将日期时间字段按照年份进行截断- 得到该年的开始日期。
-
这个函数可以用于统计某一年的数据
- 或者按年份进行分组和聚合操作。
-
下面是一个使用
TruncYear
函数的示例: -
假设我们有一个模型类
Transaction
- 其中包含一个名为
transaction_date
的日期字段 - 表示交易发生的日期。
- 我们希望按年份统计每年的交易总额。
- 其中包含一个名为
from django.db.models import Sum
from django.db.models.functions import TruncYear
from myapp.models import Transaction
# 查询每年的交易总额
yearly_totals = Transaction.objects.annotate(
year=TruncYear('transaction_date')
).values('year').annotate(
total_amount=Sum('amount')
).order_by('year')
for entry in yearly_totals:
year = entry['year']
total_amount = entry['total_amount']
print(f"{year.year}: {total_amount}")
- 在上面的示例中,我们首先使用
annotate
方法和TruncYear('transaction_date')
函数创建了一个新字段year
- 该字段对应于每个交易的年份。
- 然后使用
values
和annotate
对年份进行分组并计算每年的交易总额。 - 最后使用
order_by
对结果按照年份进行排序。 - 请注意,由于
TruncYear
函数将日期字段按照年份截断,所以在使用时需要根据自己的模型和字段名称进行相应的调整,以确保代码的正确执行。
【3】TruncDay
-
TruncDay
是Django ORM中的一个函数- 用于按照天数截断日期时间字段。
-
下面是对
TruncDay
函数的详细解释和使用案例:TruncDay
函数可以将日期时间字段按照天数进行截断- 得到该天的开始时间。
- 这个函数可以用于按天统计数据、按天进行分组和聚合操作
- 或者筛选某个特定的日期范围内的数据。
-
下面是一个使用
TruncDay
函数的示例:- 假设我们有一个模型类
Sales
,其中包含一个名为sale_date
的日期字段 - 表示销售发生的日期。
- 我们希望按天统计每天的销售总额。
- 假设我们有一个模型类
from django.db.models import Sum
from django.db.models.functions import TruncDay
from myapp.models import Sales
# 查询每天的销售总额
daily_totals = Sales.objects.annotate(
day=TruncDay('sale_date')
).values('day').annotate(
total_amount=Sum('amount')
).order_by('day')
for entry in daily_totals:
day = entry['day']
total_amount = entry['total_amount']
print(f"{day.date()}: {total_amount}")
- 在上面的示例中
- 我们首先使用
annotate
方法和TruncDay('sale_date')
函数创建了一个新字段day
- 该字段对应于每个销售的日期。
- 然后使用
values
和annotate
对日期进行分组并计算每天的销售总额。 - 最后使用
order_by
对结果按照日期进行排序。
- 我们首先使用
- 请注意
- 由于
TruncDay
函数将日期字段按照天数截断 - 所以在使用时需要根据自己的模型和字段名称进行相应的调整,以确保代码的正确执行。
- 由于