Django休息框架反向关系字段数据从validated_data中省略

时间:2016-03-04 05:30:42

标签: python django django-rest-framework

模型:

class Questionnaire(models.Model):
    ...

class Question(models.Model):
    ...
    questionnaire = models.ForeignKey('Questionnaire', related_name='questions', blank=True, null=True)
    ...

串行器:

class QuestionSerializer(serializers.ModelSerializer):
    choices = MultipleChoiceSerializer(many=True)
    children = RecursiveField(many=True)

    class Meta:
        model = Question
        fields = [
            'id',
            'text',
            'order',
            'choices',
            #'parent',
            'children',
            'type',
            'category',
            'requiredif',
            'max_answers',
            'min_answers',
        ]

class QuestionnaireCreateUpdateSerializer(serializers.ModelSerializer):
    questions = QuestionSerializer(many=True)

    class Meta:
        model = Questionnaire
        fields = [
            'id',
            'questions',
            'name',
            'description',
        ]

        def create(self, validated_data):
            print validated_data
            ...

使用{'name': 'a', 'description': 'b', 'questions': [{'category': 'a', 'min_answers': 1}]}验证_data:

{u'name': u'a', u'questions': [], u'description': u'b'}

简单测试:

def test_submit_qnr(self):
        self.client.force_login(self.user.user)
        qnr2 = {'name': 'a', 'description': 'b', 'questions': [{'category': 'a', 'min_answers': 1}]}
        response = self.client.post('/api/qnr/', data=qnr2)
        print response.json()
        response.json()['questions'].should_not.equal([])  # fails!

JSON回复:

{u'description': u'b', u'id': 1, u'questions': [], u'name': u'a'}

我想编写嵌套字段并覆盖create来执行此操作,但验证似乎存在问题,因为嵌套模型的数据将在validated_data中删除。 我尝试在create函数的顶部打印validated_data变量,并且由于我不明白questions字段是空列表的原因。 api-guide文档中的关系部分显示了几乎完全相同的示例。我错过了什么?

EDIT1:

直接在shell中测试时,序列化程序按预期工作,但由于某种原因,它在测试用例中失败

编辑2: 视图:

class QuestionnaireViewSet(viewsets.ModelViewSet):
    authentication_classes = [SessionAuthentication, BasicAuthentication, JSONWebTokenAuthentication]
    permission_classes = [permissions.IsAuthenticated, ]
    queryset = Questionnaire.objects.all()
    serializer_class = QuestionnaireCreateUpdateSerializer

网址:

router = routers.DefaultRouter()
router.register(r'qnr', QuestionnaireViewSet)

urlpatterns = [
    ...
    url(r'^api/', include(router.urls)),
    ]

1 个答案:

答案 0 :(得分:2)

由于您遵循api-guide中提供的示例并且它在shell中工作,我认为数据未正确发送。

Django Rest Framework使用APIClient进行测试,该测试基于Django的Test Client

如果您未提供content type,则默认值为multipart/form-data

  

如果您没有为content_type提供值,则data中的值将以multipart/form-data的内容类型进行传输。在这种情况下,数据中的键值对将被编码为multipart消息,并用于创建POST数据有效负载。

您需要将format数据明确指定为json

response = self.client.post('/api/qnr/', data=qnr2, format='json')