Django Rest Framework with ChoiceField

前端 未结 8 1940
轮回少年
轮回少年 2020-12-02 06:01

I have a few fields in my user model that are choice fields and am trying to figure out how to best implement that into Django Rest Framework.

Below is some simplifi

8条回答
  •  天涯浪人
    2020-12-02 06:12

    I prefer the answer by @nicolaspanel to keep the field writeable. If you use this definition instead of his ChoiceField, you take advantage of any/all of the infrastructure in the built-in ChoiceField while mapping the choices from str => int:

    class MappedChoiceField(serializers.ChoiceField):
    
        @serializers.ChoiceField.choices.setter
        def choices(self, choices):
            self.grouped_choices = fields.to_choices_dict(choices)
            self._choices = fields.flatten_choices_dict(self.grouped_choices)
            # in py2 use `iteritems` or `six.iteritems`
            self.choice_strings_to_values = {v: k for k, v in self._choices.items()}
    

    The @property override is "ugly" but my goal is always to change as little of the core as possible (to maximize forward compatibility).

    P.S. if you want to allow_blank, there's a bug in DRF. The simplest workaround is to add the following to MappedChoiceField:

    def validate_empty_values(self, data):
        if data == '':
            if self.allow_blank:
                return (True, None)
        # for py2 make the super() explicit
        return super().validate_empty_values(data)
    

    P.P.S. If you have a bunch of choice fields that all need to be mapped this, way take advantage of the feature noted by @lechup and add the following to your ModelSerializer (not its Meta):

    serializer_choice_field = MappedChoiceField
    

提交回复
热议问题