Django ChoiceField返回索引而非实际名称的问题求助
values()返回外键ID而非关联字段值的问题 看起来你遇到的问题是Django的values()方法特性导致的——它直接从数据库拉取原始字段值,不会触发模型实例的方法,也不会自动关联外键的显示值。咱们一步步来解决:
先明确你的模型关系
从你给出的结果来看,WebTokens的web_field_type应该是外键关联到WebFieldType模型(因为返回的是ID 1,对应WebFieldType里的FACEBOOK/INSTAGRAM)。如果是ChoiceField的话,我也会给出对应的解决办法。
情况1:web_field_type是外键关联WebFieldType
这时候最直接的办法是用Django的双下划线跨表查询,直接在values()里指定关联模型的字段:
WebTokens.objects.all().values('token_name', 'web_field_type__webfield_type')
这样返回的结果就会是:[{'token_name': 'some_token_name', 'web_field_type__webfield_type': 'FACEBOOK'}]
如果想给这个字段重命名(比如改成webfield_type和之前的习惯一致),可以用annotate结合F表达式:
from django.db.models import F WebTokens.objects.all() .annotate(webfield_type=F('web_field_type__webfield_type')) .values('token_name', 'webfield_type')
这样返回的结构就和你预期的一样了:[{'token_name': 'some_token_name', 'webfield_type': 'FACEBOOK'}]
情况2:web_field_type是模型内的ChoiceField
如果你的web_field_type是定义在WebTokens里的ChoiceField(比如WEB_FIELD_TYPE_CHOICES = [(1, 'FACEBOOK'), (2, 'INSTAGRAM')]),那get_webfield_type_display()是实例方法,values()不会调用它。这时候可以用Case和When来映射显示值:
from django.db.models import Case, When, Value, CharField # 假设你的Choice定义是WebTokens.WEB_FIELD_TYPE_CHOICES WebTokens.objects.annotate( webfield_type=Case( *[When(web_field_type=val, then=Value(label)) for val, label in WebTokens.WEB_FIELD_TYPE_CHOICES], output_field=CharField() ) ).values('token_name', 'webfield_type')
为什么你之前的方法无效?
你在模型里添加的return '{}'.format(self.get_webfield_type_display())应该是写在__str__方法里?但values()方法根本不会创建模型实例——它直接生成SQL查询,从数据库读取原始字段值,所以模型里的任何实例方法都不会被执行,自然拿不到显示名称。
内容的提问来源于stack exchange,提问作者newbie

