2016-05-16 71 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) 
相關問題