簡體   English   中英

使用注釋時 Django 中選擇字段的顯示名稱

[英]Display name of a choice field in Django while using annotate

我試圖在使用 annotate 時獲取選項的顯示名稱,但我一直無法弄清楚。 我有以下查詢:

Survey.objects.values('what').annotate(count=Count('why')).order_by()

結果是:

[{'count': 34, 'what': u'a'}, 
{'count': 39, 'what': u'c'}, 
{'count': 40, 'wat': u'p'}]

但我想要一些顯示選擇字段名稱而不是鍵的東西:

[{'count': 34, 'what': u'appreciative'}, 
{'count': 39, 'what': u'creative'}, 
{'count': 40, 'wat': u'promising'}]

我嘗試了 get_what_display (如文檔和有關此主題的其他 stackoverflow 答案中所述),但 django 引發錯誤。 即以下似乎不起作用

Survey.objects.values('get_what_display').annotate(count=Count('why')).order_by()

正如前面所說, get_FOO_display是一個實例方法,而不是你可以在.values()使用的東西。 因此,我會用 Pythonic 的方式來完成你想做的事情:

from django.utils.encoding import force_text

survey_counts = Survey.objects.values('what').annotate(count=Count('why')).order_by()

choices = dict(Survey._meta.get_field_by_name('what')[0].flatchoices)
for entry in survey_counts:
    entry['what'] = force_text(choices[entry['what']], strings_only=True)

要在不迭代查詢集的情況下完成此操作,您可以使用條件表達式來注釋 display 屬性。 帶注釋的屬性可用於.values()

from django.db.models import Case, CharField, Value, When

choices = dict(Survey._meta.get_field('what')[0].flatchoices)
whens = [When(what=k, then=Value(v)) for k, v in choices.items()]
survey_counts = (
    Survey.objects
    .annotate(get_what_display=Case(*whens, output_field=CharField()))
    .values('get_what_display')
    .annotate(count=Count('why'))
    .order_by()
)

基於@bdoubleu 的回答,我編寫了以下通用條件表達式:

# myapp/utils.py
from django.db.models import Case, CharField, Value, When

class WithChoices(Case):
    def __init__(self, model, field, condition=None, then=None, **lookups):
        choices = dict(model._meta.get_field(field).flatchoices)
        whens = [When(**{field: k, 'then': Value(v)}) for k, v in choices.items()]
        return super().__init__(*whens, output_field=CharField())

# example usage
from myapp.utils import WithChoices
from myapp.models import MyModel
MyModel.objects.annotate(what_with_choices=WithChoices(MyModel, 'what')).values('what_with_choices')

可能有一種更簡潔的構建方式,不需要將model arg 傳遞給 WithChoices,但是,嘿,這是可行的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM