Django - 使用 get_FOO_display 进行聚合

问题描述 投票:0回答:3

考虑以下因素:

status = queryset.values('status').annotate(count=Count('status'))

其中

status
字段是带有
CharField
choices
。这将产生一个带有
status
DB 值及其计数的字典列表。

有没有办法聚合

status
并显示其显示值?我查了
_get_FIELD_display
的代码,我可能可以模仿它,但重复框架的内部代码感觉有点黑客。

django django-orm django-aggregation
3个回答
6
投票

如果不破解 SQL,您可能无法轻松在数据库级别实现这一目标。但是,由于

get_FOO_display
Model
级别上运行,您甚至不必破解
_get_FIELD_display
或手动查找选择(如果以下方法不会花费您的服务器太多费用):

YourModel(status=status).get_status_display()

因此

for s in queryset.values('status').annotate(count=Count('status')):
    print(queryset.model(status=s['status']).get_status_display())

1
投票

看一下

django.contrib.admin.util.display_for_field
函数。你必须找到字段对象:

field = queryset.model._meta.get_field('status')
        

然后您可以将其用作:

display_for_field(status, field)

或者,就您而言:

{ unicode(display_for_field(t['status'], field)): t['count']
    for t in queryset.values('taxonomy').annotate(count=models.Count('taxonomy'))}

0
投票

在 Django >2 上,我通常将带注释的数据集转换为字典列表,然后应用此函数:

dataset =list(MyModel.objects.all().values('status').annotate(count=Count('id')))
dataset = transform_display(dataset,MyModel,'status')

def transform_display(dataset, model_class, field_name):
    for item in dataset:
        field_value = item[field_name]
        instance = model_class(**{field_name: field_value})
        display_method = getattr(instance, f"get_{field_name}_display", None)
        new_value = display_method()
        if new_value:
            item[field_name] = new_value
    return dataset
© www.soinside.com 2019 - 2024. All rights reserved.