2016-05-16 48 views
0

的相关值我有一个选择场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',) 

回答

1

以下方法解决了这个问题。我们可以为选择创建一个自定义字段。

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建议的解决方案类似,但采用更清洁的方式。

4

的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) 
相关问题