如何发送一个选择字段
的相关值我有一个选择场status
称为Ticket
型号:如何发送一个选择字段
STATUS_CHOICES = (
('1', 'Open'),
('2', 'Resolved'),
('3', 'Won\'t fix')
)
status = models.CharField(
"Status",
max_length=1,
choices=STATUS_CHOICES,
blank=False,
default='1'
)
我使用Django的REST框架的API。默认模型串行器发送第一个选择值,即1
而不是Open
。我怎样才能让它发送第二个文本值作为回应。
这里是我的串行的一部分:
class TicketSerializer(serializers.ModelSerializer):
status = serializers.ChoiceField(choices=Ticket.STATUS_CHOICES)
class Meta:
model = Ticket
fields = ('status',)
以下方法解决了这个问题。我们可以为选择创建一个自定义字段。
class ChoicesField(serializers.Field):
def __init__(self, choices, **kwargs):
self._choices = choices
super(ChoicesField, self).__init__(**kwargs)
def to_representation(self, obj):
return self._choices[int(obj) - 1] # obj is the first value
def to_internal_value(self, data):
return getattr(self._choices, data)
这与Tahir建议的解决方案类似,但采用更清洁的方式。
的API通常用于获取数据,而不是数据的UI表示。在('1', 'Choice 1')
中,'1'
是要在任何地方存储和使用的值,'Choice 1'
是我们在需要时显式使用它的UI表示(在UI中即模板)。
DjangoAdmin是一个完整的Django应用程序,因此它明确使用了UI表示。如果你使用Django Forms,你也需要明确地使用它。它不会自动使用。
在模板中,如果你做{{ my_form_choice_field.value }}
它将使用'1'
而不是'Choice 1'
。你需要明确地使用{{ my_form_choice_field.get_my_form_choice_field_display }}
(在UI层)得到'Choice 1'
。
因此,当我开始使用API时,通常用于提取数据,而不是用户界面表示。这就是为什么(JUST LIKE DJANGO)DjangoRestFramework也只使用原始值而不是它的UI表示。
现在要回答你的问题,如果你真的想要返回的UI表示。然后,您需要重写BaseSerializer的to_representation
方法以用其UI用户界面替换值并覆盖to_internal_value
以在保存时将UI表示重新替换为值。
您可以看到一个示例(来自文档)here。
引用文档示例代码在此处链接。
class HighScoreSerializer(serializers.BaseSerializer):
def to_internal_value(self, data):
score = data.get('score')
player_name = data.get('player_name')
# Perform the data validation.
if not score:
raise ValidationError({
'score': 'This field is required.'
})
if not player_name:
raise ValidationError({
'player_name': 'This field is required.'
})
if len(player_name) > 10:
raise ValidationError({
'player_name': 'May not be more than 10 characters.'
})
# Return the validated values. This will be available as
# the `.validated_data` property.
return {
'score': int(score),
'player_name': player_name
}
def to_representation(self, obj):
return {
'score': obj.score,
'player_name': obj.player_name
}
def create(self, validated_data):
return HighScore.objects.create(**validated_data)