Django get choice display on using .价值观

lndjwyie  于 2023-05-01  发布在  Go
关注(0)|答案(4)|浏览(152)

对于带有字段typeModel,是否有任何方法可以在使用Model.objects.values()时获得选择的显示值?我试过Model.objects.values('get_type_display'),但它不工作。

j8ag8udp

j8ag8udp1#

你不能这么做values是django内置的queryset方法,用于获取数据字典而不是模型示例,你可以在这里阅读更多关于它的信息。
将选择与字段的模型附加在一起的常规(也是正确的)方法是使用像这样的静态变量。

class MyModel(models.Model):
    TYPE_CHOICES = (
        # (<DB VALUE>, <DISPLAY_VALUE>)
        ('a', 'Choice A'),
        ('b', 'Choice B'),
    )

    type = models.CharField(max_length=1, choices=TYPE_CHOICES)

您可以像这样访问模型外的类型字段的选择。

MyModel.TYPE_CHOICES
wrrgggsh

wrrgggsh2#

当我在查询集中调用.values of choice字段时,我以下面的方式处理:
假设以下模型

from enum import Enum

class TypeChoice(Enum):
    a = 'class A'
    b = 'class B'

class MyModel(models.Model):
    type = models.CharField(max_length=1, choices=[(tag.name,tag.value) for tag in TypeChoice])

使用查询my_qset = MyModel.objects.values('type'),显示值如下:

for item in my_qset:
     print(TypeChoice[item].value)

为了在我的模板中处理这个问题,我写了一个自定义模板过滤器,比如type_display

from django import template
import TypeChoice
register = template.Library()

@register.filter
def type_display(var):
    return TypeChoice[var].value
vmpqdwk3

vmpqdwk33#

我也有类似的需求,不幸的是,你不能只使用values;但是,您可以使用一些巧妙的注解和django自定义枚举(IntegerChoices/TextChoices)类来做类似的事情。
我从另一个SO问题创造了这个,但我不记得我从哪里得到的灵感。基本上,您可以通过查询集上的注解传入相应的模型或您希望Map回标签的选择。

class ChoicesLabelCase(Case):
    def __init__(self, field: str, model: Model = None, choices: list = None, *args, **kwargs) -> None:
        if choices is None and model is None:
            raise ValueError("Either a model or a choices parameter must be provided.")
        elif choices is None:
            choices = model._meta.get_field(field).flatchoices

        cases_list = [When(**{field: val, "then": Value(label)}) for (val, label) in choices]
        super(ChoicesLabelCase, self).__init__(*cases_list, output_field=CharField(), *args, **kwargs)

以这个模型为例:

class FruitType(models.IntegerChoices):
    APPLE = 1, 'Apple'
    BANANA = 2, 'Banana'
    ORANGE = 3, "Orange"

class Fruit(models.Model):
    type = models.IntegerField(choices=FruitType.choices)

您可以像这样注解标签:

>>> Fruit.objects.all().annotate(
    type_label=ChoicesLabelCase('type', FruitType)
).values("type", "type_label")

[
    {'type': 1, 'type_label': 'Apple'}, 
    {'type': 2, 'type_label': 'Banana'}, 
    ...
]
55ooxyrt

55ooxyrt4#

此代码示例可以帮助您:

alertsfilter = list(Alerte.objects.filter(viewed__isnull=False).values(
    'id', 
    'type', 
    'created_at', 
    'viewed',
    'sent', 
    'agent_id', 
    'geofence_id', 
    'objet__id', 
    'objet__nom',
    'objet__marker',
    'geofence__id'))

for alert in alertsfilter:
    # alert_type = alert['type']
    alert['type'] = Alerte.objects.get(pk=alert['id']).get_type_display()

相关问题