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
相关产品推荐
相关产品推荐

