DRF:一对多序列化

时间:2019-06-15 04:44:00

标签: django-rest-framework

序列化问题时尝试打印问题的所有答案,但难以告诉django如何查找父对象。

目标是返回如下内容:

[
  {
    uuid: 1,
    question: 'Question 1',
    answers: [
      {'uuid': 1, 'answer': "A"},
      {'uuid': 2, 'answer': "B"},
      {'uuid': 3, 'answer': "C"},
    ],
  },
]

models.py

class Question(models.Model):
    uuid = ShortUUIDField(unique=True, blank=False, editable=False, default=shortuuid.uuid())
    question = models.CharField(max_length=140)
    creator = models.ForeignKey(CustomUser, on_delete=models.CASCADE, blank=True, null=True)
    def __str__(self):
        return '{}'.format(self.question)
    class Meta:
        indexes = [
            models.Index(fields=['uuid']),
        ]

class Answer(models.Model):
    uuid = ShortUUIDField(unique=True, blank=False, editable=False, default=shortuuid.uuid())
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    answer = models.CharField(max_length=70)
    creator = models.ForeignKey(CustomUser, on_delete=models.CASCADE, blank=True, null=True)
    def __str__(self):
        return '{}'.format(self.answer)
    class Meta:
        indexes = [
            models.Index(fields=['uuid']),
        ]

serializers.py

class AnswerSerializer(serializers.ModelSerializer):
    creator = ProfileSerializer(read_only = True)
    class Meta:
        model = models.Answer
        fields = ('uuid','answer', 'creator','question')
class QuestionSerializer(serializers.ModelSerializer):
    creator = ProfileSerializer(read_only = True)
    question_answer = AnswerSerializer(many=True,source='id')
    class Meta:
        model = models.Question
        fields = ('uuid','question', 'creator', 'question_answer')

views.py

class QuestionViewSet(viewsets.ModelViewSet):
    queryset = models.Question.objects.all()
    serializer_class = serializers.QuestionSerializer

引发错误

Traceback (most recent call last):
  File "\Backend\env\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "\Backend\env\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "\Backend\env\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "\Backend\env\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "\Backend\env\lib\site-packages\rest_framework\viewsets.py", line 116, in view
    return self.dispatch(request, *args, **kwargs)
  File "\Backend\env\lib\site-packages\rest_framework\views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "\Backend\env\lib\site-packages\rest_framework\views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "\Backend\env\lib\site-packages\rest_framework\views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "\Backend\env\lib\site-packages\rest_framework\mixins.py", line 48, in list
    return Response(serializer.data)
  File "\Backend\env\lib\site-packages\rest_framework\serializers.py", line 768, in data
    ret = super(ListSerializer, self).data
  File "\Backend\env\lib\site-packages\rest_framework\serializers.py", line 262, in data
    self._data = self.to_representation(self.instance)
  File "\Backend\env\lib\site-packages\rest_framework\serializers.py", line 686, in to_representation
    self.child.to_representation(item) for item in iterable
  File "\Backend\env\lib\site-packages\rest_framework\serializers.py", line 686, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "\Backend\env\lib\site-packages\rest_framework\serializers.py", line 530, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "\Backend\env\lib\site-packages\rest_framework\serializers.py", line 686, in to_representation
    self.child.to_representation(item) for item in iterable
TypeError: 'int' object is not iterable

1 个答案:

答案 0 :(得分:3)

我认为该错误是由您在source='id'上使用QuestionSerializer.question_answer引起的。使用source='id'意味着序列化程序将使用id上的Question字段来检索答案。

我建议您解决此问题的方法是

  1. related_name字段添加一个Answer.question参数,例如question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='answers')

  2. 更新序列化程序以在字段上使用反向关系的名称Question.answers

    class QuestionSerializer(serializers.ModelSerializer):
        creator = ProfileSerializer(read_only = True)
        answers = AnswerSerializer(many=True, read_only=True)
        class Meta:
            model = models.Question
            fields = ('uuid','question', 'creator', 'answers')