django用动态列名注释

时间:2019-02-11 15:01:14

标签: django dynamic pivot annotate

我在Django应用中有一个模型,其结构如下:

class items(models.Model):
    name = models.CharField(max_length=50)
    location = models.CharField(max_length=3)

我想为每个名称/项目的每个位置的数量创建一个数据透视表,我设法按照以下步骤进行操作:

queryset_res = items.objects.values('name')\
                            .annotate(NYC=Sum(Case(When(location='NYC', then=1),default=Value('0'),output_field=IntegerField())))\
                            .annotate(LND=Sum(Case(When(location='LND', then=1),default=Value('0'),output_field=IntegerField())))\
                            .annotate(ASM=Sum(Case(When(location='ASM', then=1),default=Value('0'),output_field=IntegerField())))\
                            .annotate(Total=Count('location'))\
                            .values('name', 'NYC', 'LSA','Total')\
                            .order_by('-Total')

这给了我每个名字在每个位置出现多少次了。

我的问题是如何使位置动态化,所以如果添加的新位置没有回来,请再次更改代码!从列表或从模型数据本身

非常感谢 AB

1 个答案:

答案 0 :(得分:1)

您可以在python中将动态参数与*[1, 2, 3]**{'key': 'value'}绑定。

def get_annotation(key='NYC'):
    return {
        key: Sum(Case(When(localtion=key), then=1), default=Value('0'), output_field=IntegerField()),
    }

queryset_res = items.objects.values('name')
location_list = ['NYC', 'LSA', 'ASM', ...etc]
for key in location_list:
    queryset_res = queryset_res.annotate(**get_annotation(key))

queryset_res = queryset_res.annotate(Total=Count('location')) \
    .values('name', 'Total', *location_list) \
    .order_by('-Total')

现在,您只需更改location_list即可实现一组查询。