You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pytest中Django REST Framework嵌套Serializer验证失败问题

问题排查与解决步骤
  • 检查测试请求的内容格式
    Postman默认以JSON格式发送请求,而pytest中使用APIClient或Django测试客户端时,若未指定content_type='application/json'或format='json',Django会将请求数据解析为表单格式,导致嵌套字段无法被Serializer正确识别,触发必填错误。
    错误写法:

    client.put(url, data={"users": [1, 2]})
    

    正确写法二选一:

    # 方式1:手动序列化JSON并指定content_type
    import json
    response = client.put(url, data=json.dumps({"users": [1, 2]}), content_type='application/json')
    # 方式2:使用DRF的format参数自动处理JSON
    response = client.put(url, data={"users": [1, 2]}, format='json')
    
  • 对比测试与Postman的请求数据结构
    在ViewSet的assign_course方法中打印request.data,和Postman发送的原始数据做对比:

    def assign_course(self, request, *args, **kwargs):
        print("Request Data:", request.data)  # 打印测试时的请求数据
        serializer = CourseAssignListSerializer(data=request.data)
        # ... 后续逻辑
    

    如果测试中request.data的结构(比如ID是字符串而非数字)或字段名称和Postman不一致,需调整测试数据格式。

  • 确认Serializer的字段定义
    检查CourseAssignListSerializer中users字段的配置:

    • 如果是PrimaryKeyRelatedField(many=True, queryset=User.objects.all()),则直接传ID数组是正确的;
    • 如果是嵌套Serializer(比如UserSerializer(many=True)),则需传包含用户字段的字典数组(如[{"id":1, "name":"xxx"}, ...])。
      由于Postman请求正常,说明字段定义没问题,重点还是测试请求的格式问题。
  • 检查ViewSet中Serializer的初始化逻辑
    确保assign_course方法中是直接使用request.data初始化Serializer,而非手动拼接或修改数据:

    def assign_course(self, request, *args, **kwargs):
        # 正确:直接使用request.data
        serializer = CourseAssignListSerializer(data=request.data)
        # 错误:不要手动修改request.data,比如转成表单格式
        # serializer = CourseAssignListSerializer(data=request.POST)
        if serializer.is_valid(raise_exception=True):
            # 处理分配逻辑
            return Response(serializer.data)
    

内容的提问来源于stack exchange,提问作者Fikra Laksana Putra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 15:30:56