Skip to main content
 首页 » 编程设计

python之在 Django 中获取按月分组的结果

2025年02月15日36JeffreyZhao

我想从 Member 模型中获取所有成员,并获取他们每月完成的总计算。

我的查询如下:

members_list = Member.objects\ 
        .exclude(deleted=True) \ 
        .annotate(num_calculations=Count('user__calculations'))\ 
        .order_by("-user__date_joined") 

通过这个查询,我得到了所有成员和他们完成的总计算。

如何获得每月(过去 12 个月)的总计算量?

计算模型如下:

class Calculations(models.Model): 
    user = models.ForeignKey(to=User) 
    make = models.CharField(max_length=127) 
    model = models.CharField(max_length=127)         
    mileage = models.IntegerField()         
    price_date = models.DateTimeField(auto_now_add=True) 
    sales_price_currency = models.CharField(max_length=10, null=True) 

成员模型如下:

class Member(models.Model): 
    user = models.ForeignKey(to=User) 
    number = models.CharField(max_length=10)         
    company_name = models.CharField(max_length=100) 
    address = models.CharField(max_length=255) 
    mobile = models.CharField(max_length=50) 
    active = models.BooleanField() 
    deleted = models.NullBooleanField(null=True) 

请您参考如下方法:

我解决了。如果其他人需要它,这里就是解决方案。

首先我得到了每个月的所有计算如下:

items = list(Calculations.objects 
                     .filter(user__member__number=member_number) 
                     .filter(price_date__gte=datetime.datetime.now().today() - relativedelta(months=12)) 
                     .annotate(date=TruncMonth('price_date')) 
                     .values('date') 
                     .annotate(total=Count('id')) 
                     .values('date', 'total') 
                     .order_by('date')) 

但在这里我只得到用户进行计算的月份,但无论用户是否在该月进行了计算,我都需要最近 12 个月。

为了做到这一点,我接下来做了:

result = [] 
for month in range(12): 
     date = timezone.now() - relativedelta(months=month) 
     next_month = date + relativedelta(months=1) 
 
     month_results = list(filter(lambda i: date <= i['date'] + relativedelta(months=1) < nextMonth, items)) 
 
     month_result = 0 
 
     if month_results: 
        month_result = month_results[0]['total'] 
 
     result.append({'total_calculations': month_result}) 

成功了。