使用带有元组的serializers.ChoiceField时Django Rest Framework中的键错误

时间:2015-03-25 05:33:25

标签: django django-rest-framework

我正在使用Django 1.7.7和Django Rest Framework 3.1.1。

当我序列化这个模型时

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)

使用此viewset / serializer:

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键是第一个从Questions表中序列化的键)。

错误似乎是由to_representation中的rest_framework / fields.py引发的         return self.choice_strings_to_values [six.text_type(value)]

有什么明显我做错了吗?使用序列化器的元组是否存在问题.ChoiceField?

约翰

3 个答案:

答案 0 :(得分:2)

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

您可以使用两个单独的字段来解决这个问题:

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

答案 1 :(得分:2)

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

public HelpController(): this(Startup.HttpConfig)
{
    logger.Trace("Help controller created");
}

protected HelpController(HttpConfiguration config)
{
    Configuration = config;
}

您可以通过创建扩展ChoiceField类

的字段序列化程序来更改此行为
self.choice_strings_to_values = dict([
    (six.text_type(key), key) for key in self.choices.keys()
])

答案 2 :(得分:1)

Python 3上的等价物

self.choice_strings_to_values = dict([
    (six.text_type(key), str(value)) for key, value in self.choices.items()
])