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

Postman提交Django ManyToMany字段时form-data报必填错误如何解决

问题根源

form-data格式的请求被Django REST Framework解析后,request.data是QueryDict类型,而非JSON解析后的普通字典:

  • QueryDict对列表、嵌套结构的存储逻辑和普通字典不同,你手动拼入的rooms列表无法被序列化器正确识别
  • 你显式定义的rooms序列化字段默认required=True,序列化器识别不到有效rooms值就返回必填错误

解决方案(按优先级排序)

方案1:改动最小的热修复

仅需修改视图中序列化器实例化的代码,把new_request转为普通字典即可,普通字典的列表结构可以被嵌套序列化器正常识别,和raw JSON请求的处理逻辑完全一致:

# module/views.py 中修改序列化器实例化行
module_serializer = ModuleSerializer(data=dict(new_request))

方案2:逻辑优化方案(更推荐)

你实际不需要前端传入rooms字段,完全可以在序列化器层把rooms设置为只读,关联逻辑放在序列化器保存后处理,从根源避免必填校验问题:

  1. 先修改序列化器字段配置
# module/serializers.py 修改rooms字段定义
class ModuleSerializer(serializers.ModelSerializer):
    rooms = RoomSerializer(many=True, read_only=True) # 新增read_only=True参数

    class Meta:
        model = Module
        fields = '__all__'

    # 可删除原create、update方法中处理rooms关联的代码
  1. 优化视图层逻辑
# module/views.py 优化后的逻辑
class add_module(APIView):
    def post(self, request, format=None):
        module_serializer = ModuleSerializer(data=request.data)
        if module_serializer.is_valid():
            module = module_serializer.save()
            # 单独处理房间关联
            if 'room_list' in request.data:
                room_ids = request.data['room_list'].split(" ")
                rooms = Rooms.objects.filter(room_id__in=room_ids)
                module.rooms.add(*rooms)
            return Response(module.module_id)
        return Response(module_serializer.errors)

改后代码逻辑更简洁,也完全兼容form-data和JSON两种请求格式。

额外需要修复的隐性BUG

你的代码存在拼写错误会导致异常:rooms/serialier.py中的序列化器类名写为RoomSerialize,少了末尾的r,和你视图中引用的RoomSerializer不一致,需要修正:

# rooms/serializer.py 修正类名
class RoomSerializer(serializers.ModelSerializer):
    room_id = serializers.IntegerField()
    class Meta:
        model = Rooms
        fields = "__all__"

内容的提问来源于stack exchange,提问作者somya goyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:15:03