django 使用动态列名进行注释

Bel*_*jio 2 django pivot annotate dynamic

我在 django 应用程序中有一个模型,具有以下结构:

class items(models.Model):
    name = models.CharField(max_length=50)
    location = models.CharField(max_length=3)
Run Code Online (Sandbox Code Playgroud)

我想为每个名称/项目的每个位置的计数创建一个数据透视表,我设法按照以下方式进行:

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')
Run Code Online (Sandbox Code Playgroud)

这给了我每个名字在每个位置出现的次数,这一切都很好。

我的问题是如何使位置动态化,因此如果添加了新位置,我就不会再回来更改代码!来自列表或模型数据本身

非常感谢AB

Yon*_* Jo 10

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

from django.db.models import Case, Count, Sum, IntegerField, Value, When

def get_annotation(key):
    return {
        key: Sum(
            Case(
                When(location=key, then=Value(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")
)
Run Code Online (Sandbox Code Playgroud)

现在,您只需更改location_list.

  • 你好,谢谢你的回复,它工作得很好,只是做了一点修正,因为你错过了“get_annotation”中的“return key_map”,除此之外,完美,谢谢 (2认同)