选择字段中的 Return display_name
Return display_name in ChoiceField
我正在使用 ModelViewSet
和 ModelSerializer
在 DRF 中实现一些 REST API。我所有的 API 都使用 JSON 格式,我的一些模型使用 ChoiceField 字段,例如:
MyModel(models.Model):
KEY1 = 'Key1'
KEY2 = 'Key2'
ATTRIBUTE_CHOICES = (
(KEY1, 'Label 1'),
(KEY2, 'Label 2'))
attribute = models.CharField(max_length=4,
choices=ATTRIBUTE_CHOICES, default=KEY1)
我的问题是默认情况下 DRF 总是 returns(并接受)JSON 消息的这些选择的键(参见 here),但我想使用标签,因为我认为它更一致和清楚地了解谁将使用那些 APIs。有什么建议吗?
除了重写序列化程序之外别无他法。请看一下,看看它是如何完成的。
我找到了一个可能的解决方案,即定义我自己的字段如下:
class MyChoiceField(serializers.ChoiceField):
def to_representation(self, data):
if data not in self.choices.keys():
self.fail('invalid_choice', input=data)
else:
return self.choices[data]
def to_internal_value(self, data):
for key, value in self.choices.items():
if value == data:
return key
self.fail('invalid_choice', input=data)
它的工作方式与 ChoiceField
相同,但 returns 接受标签而不是键。
以前的答案对我帮助很大,但对我不起作用,因为我使用的是 Django 版本 3 和 DRF 版本 3.11,所以我想到了这个:
# models.py
class Ball(models.Model):
class Types(models.TextChoice):
VOLLYBALL = 'VB', gettext_lazy('VollyBall')
FOOTBALL = 'FB', gettext_lazy('FootBall')
type = models.CharField(max_length=2, choices=Types.choices)
# serializers.py
class CustomChoiceField(serializers.ChoiceField):
def to_representation(self, value):
if value in ('', None):
return value
choice_dict = {str(key): key.label for key in self.choices}
return choice_dict.get(str(value), value)
def to_internal_value(self, data):
if data == '' and self.allow_blank:
return ''
try:
choice_dict = {key.label: str(key) for key in self.choices}
return choice_dict[str(data)]
except KeyError:
self.fail('invalid_choice', input=data)
class BallSerializer(serializers.ModelSerializer):
type = CustomChoiceField(choices=Book.Types)
class Meta:
model = Book
fields = ['type']
我正在使用 ModelViewSet
和 ModelSerializer
在 DRF 中实现一些 REST API。我所有的 API 都使用 JSON 格式,我的一些模型使用 ChoiceField 字段,例如:
MyModel(models.Model):
KEY1 = 'Key1'
KEY2 = 'Key2'
ATTRIBUTE_CHOICES = (
(KEY1, 'Label 1'),
(KEY2, 'Label 2'))
attribute = models.CharField(max_length=4,
choices=ATTRIBUTE_CHOICES, default=KEY1)
我的问题是默认情况下 DRF 总是 returns(并接受)JSON 消息的这些选择的键(参见 here),但我想使用标签,因为我认为它更一致和清楚地了解谁将使用那些 APIs。有什么建议吗?
除了重写序列化程序之外别无他法。请看一下
我找到了一个可能的解决方案,即定义我自己的字段如下:
class MyChoiceField(serializers.ChoiceField):
def to_representation(self, data):
if data not in self.choices.keys():
self.fail('invalid_choice', input=data)
else:
return self.choices[data]
def to_internal_value(self, data):
for key, value in self.choices.items():
if value == data:
return key
self.fail('invalid_choice', input=data)
它的工作方式与 ChoiceField
相同,但 returns 接受标签而不是键。
以前的答案对我帮助很大,但对我不起作用,因为我使用的是 Django 版本 3 和 DRF 版本 3.11,所以我想到了这个:
# models.py
class Ball(models.Model):
class Types(models.TextChoice):
VOLLYBALL = 'VB', gettext_lazy('VollyBall')
FOOTBALL = 'FB', gettext_lazy('FootBall')
type = models.CharField(max_length=2, choices=Types.choices)
# serializers.py
class CustomChoiceField(serializers.ChoiceField):
def to_representation(self, value):
if value in ('', None):
return value
choice_dict = {str(key): key.label for key in self.choices}
return choice_dict.get(str(value), value)
def to_internal_value(self, data):
if data == '' and self.allow_blank:
return ''
try:
choice_dict = {key.label: str(key) for key in self.choices}
return choice_dict[str(data)]
except KeyError:
self.fail('invalid_choice', input=data)
class BallSerializer(serializers.ModelSerializer):
type = CustomChoiceField(choices=Book.Types)
class Meta:
model = Book
fields = ['type']