Return display_name in ChoiceField

前端 未结 3 1853
耶瑟儿~
耶瑟儿~ 2021-01-15 03:06

I\'m implementing some REST API in DRF with ModelViewSet and ModelSerializer. All my APIs use the JSON format and some of my models use ChoiceField

相关标签:
3条回答
  • 2021-01-15 03:20

    There's no way other than overriding your serializer. Please take a look here, to see how it can be done.

    0 讨论(0)
  • 2021-01-15 03:32

    I found a possible solution, namely defining my own field as follow:

    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)
    

    It works the same way as to ChoiceField, but returns and accepts labels instead of keys.

    0 讨论(0)
  • 2021-01-15 03:34

    previous answers helped me a lot but not worked for me as I use Django version 3 and DRF version 3.11 , so I came up with this:

    # 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']
    
    
    0 讨论(0)
提交回复
热议问题