首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将serializers.ChoiceField与元组一起使用时,Django Rest框架中的关键错误

将serializers.ChoiceField与元组一起使用时,Django Rest框架中的关键错误
EN

Stack Overflow用户
提问于 2015-03-25 13:33:25
回答 3查看 3K关注 0票数 1

我使用的是Django 1.7.7和Django Rest Framework 3.1.1。

当我序列化这个模型时

代码语言:javascript
复制
class Question(models.Model):
  QUESTION_TYPES = (
    (10,'Blurb'),
    (20,'Group Header'),
    (21,'Group Footer'),
    (30,'Sub-Group Header'),
    (31,'Sub-Group Footer'),
    (50,'Save Button'),
    (100,'Standard Question'),
    (105,'Text-Area Question'),
    (110,'Multiple-Choice Question'),
    (120,'Standard Sub-Question'),
    (130,'Multiple-Choice Sub-Question')
)
type = models.IntegerField(default=100,choices=QUESTION_TYPES)

使用此视图集/序列化程序:

代码语言:javascript
复制
class QuestionSerializer(serializers.ModelSerializer):
   type = serializers.ChoiceField(choices='QUESTION_TYPES')

   class Meta:
      model = Question    

class QuestionViewSet(viewsets.ModelViewSet):
   model = Question
   serializer_class = QuestionSerializer

   def get_queryset(self):
      return Question.objects.all()

我得到一个KeyError '10‘(或者任何QUESTION_TYPES键是从问题表中序列化的第一个键)。

该错误似乎是由to_representation返回self.choice_strings_to_valuessix.text_type(value)中的rest_framework/fields.py抛出的

有没有什么明显的地方是我做错了?在serializer.ChoiceField中使用元组有问题吗?

约翰

EN

回答 3

Stack Overflow用户

发布于 2015-03-26 02:18:08

在尝试覆盖序列化程序本身的行为时,ChoiceField似乎有一些问题。

不过,您可以通过使用两个单独的字段来绕过此问题:

代码语言:javascript
复制
class QuestionSerializer(serializers.ModelSerializer):
    type = serializers.ChoiceField(choices=Question.QUESTION_TYPES)
    type_display = serializers.CharField(source='get_type_display',
                                         read_only=True)

    class Meta:
        model = Question
票数 2
EN

Stack Overflow用户

发布于 2015-07-10 01:30:50

这一切都归结于ChoiceField类中的这个line。它使用密钥两次。

代码语言:javascript
复制
self.choice_strings_to_values = dict([
    (six.text_type(key), key) for key in self.choices.keys()
])

您可以通过创建自己的字段序列化程序来扩展ChoiceField类来更改此行为

代码语言:javascript
复制
class DisplayChoiceFieldSerializers(serializers.ChoiceField):
    def __init__(self, *args, **kwargs):
        super(DisplayChoiceFieldSerializers, self).__init__(*args, **kwargs)
        self.choice_strings_to_values = dict([
            (six.text_type(key), unicode(value)) for key, value in self.choices.iteritems()
        ])
票数 2
EN

Stack Overflow用户

发布于 2016-02-23 18:37:00

Python 3上的等价物

代码语言:javascript
复制
self.choice_strings_to_values = dict([
    (six.text_type(key), str(value)) for key, value in self.choices.items()
])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29248164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档