如何在 Django 中显示多个模型注释的所有日期

How to display all dates for multiple model annotations in django

所以我在一个网站上工作,我想要某种摘要页面来显示我拥有的数据。假设我有这些模型:

class IceCream(TimeStampedModel):
    name = models.CharField()
    color = models.CharField()


class Cupcake(TimeStampedModel):
    name = models.CharField()
    icing = models.CharField()

所以在此页面上,用户将能够输入摘要的日期范围。我正在使用 DRF 序列化数据并在视图操作中显示它们。收到筛选日期后,我将使用 TimeStampedModel 中创建的字段筛选出 IceCream 对象和 Cupcake 对象。

@action(detail=False, methods=['get'])
def dessert_summary(self, request, **kwargs):
    start_date = self.request.query_params.get('start_date')
    end_date = self.request.query_params.get('end_date')
    cupcakes = Cupcake.objects.filter(created__date__range=[start_date, end_date])
    ice_creams = IceCream.objects.filter(created__date__range=[start_date, end_date])

过滤后,我想统计在那段时间内创建的纸杯蛋糕总数和冰淇淋总数。但我还想按日期对它们进行分组,并根据该日期显示冰淇淋和纸杯蛋糕的总数。所以我试着像这样注释查询集:

cupcakes = cupcakes.annotate(date=TruncDate('created'))
cupcakes = cupcakes.values('date')
cupcakes = cupcakes.annotate(total_cupcakes=Count('id'))
ice_creams = ice_creams.annotate(date=TruncDate('created'))
ice_creams = ice_creams.values('date')
ice_creams = ice_creams.annotate(total_ice_creams=Count('id'))

所以我希望结果是这样的:

{
    'summary': [{
        'date': "2020-09-24",
        'total_ice_creams': 10,
        'total_cupcakes': 7,
        'total_dessert': 17
    }, {
        'date': "2020-09-25',
        'total_ice_creams': 6,
        'total_cupcakes': 5,
        'total_dessert': 11
    }]
}

但现在这就是我得到的:

{
    'summary': [{
        'cupcakes': [{
            'date': "2020-09-24",
            'total_cupcakes': 10,
        }, {
            'date': "2020-09-25",
            'total_cupcakes': 5,
        }],
        'ice_creams': [{
            'date': "2020-09-24",
            'total_ice_creams': 7,
        }, {
            'date': "2020-09-27",
            'total_ice_creams': 6,
        }]
    }]
}

我想问的是如何获取两个查询集的所有日期,将冰淇淋和纸杯蛋糕相加,以及return 与预期结果一样的数据?预先感谢您的帮助!

因此,您可以执行以下操作:

  • 将所有 icecream/cupcakes 计数数据收集到字典中
icecream_dict = {obj['date']: obj['count'] for obj in ice_creams}
cupcakes_dict = {obj['date']: obj['count'] for obj in cupcakes}  
  • 创建包含所有日期的排序列表
all_dates = sorted(set(list(icecream_dict.keys()) + list(cupcakes_dict.keys())))   
  • 创建一个包含每个日期的项目及其计数的列表
result = []
for each_date in all_dates:                                                                                                                                                                               
    total_ice_creams = icecream_dict.get(each_date, 0)                                                                                                                                                                 
    total_cupcakes = cupcakes_dict.get(each_date, 0)                                                                                                                                                                 
    res = {
        'date': each_date, 
        'total_ice_creams': total_ice_creams, 
        'total_cupcakes': total_cupcakes, 
        'total_dessert': total_ice_creams + total_cupcakes
    }                                                                                                   
    result.append(res)

# check the result
print(result) 

提示:如果您计划添加更多 desert-like 模型,请考虑有一个基础模型 Desert 您可以直接查询而不是查询每个沙漠输入模型。