Django REST Framework接收React嵌套FormData无法保存关联广告数据
问题根因与修复方案
DRF 自带的 MultiPartParser 解析器默认不支持 ads[0][property] 这种方括号嵌套的 FormData 键名格式,会把所有嵌套字段解析为独立的扁平键,无法被序列化器识别为合法的嵌套数组结构,最终导致广告关联数据无法正常入库。
修复方案
方案1:前端调整FormData转换规则(改造成本最低)
将原转换工具生成的方括号键名格式,替换为DRF可直接识别的点分隔格式即可:
- 原键名
ads[0][title]修改为ads.0.title - 替换原有转换逻辑的键名生成部分,示例代码如下:
function objectToFormData(obj, form, namespace) { const fd = form || new FormData(); let formKey; for(const property in obj) { if(obj.hasOwnProperty(property)) { formKey = namespace ? `${namespace}.${property}` : property; // 数组类型处理 if(Array.isArray(obj[property])) { obj[property].forEach((item, index) => { objectToFormData(item, fd, `${formKey}.${index}`); }) // 普通对象类型处理(排除文件对象) } else if(typeof obj[property] === 'object' && !(obj[property] instanceof File)) { objectToFormData(obj[property], fd, formKey); } else { fd.append(formKey, obj[property]); } } } return fd; }
方案2:后端适配原有方括号格式(无需修改前端代码)
如果不想改动前端转换逻辑,可在DRF视图层新增自定义解析逻辑:
- 自行实现解析函数,将QueryDict中
ads[0][title]格式的键名转换为嵌套字典数组,赋值给request.data后再进入序列化流程,也可直接使用django-querydict-parser这类第三方包完成解析。
序列化器配置校验
确保订单序列化器已配置嵌套广告序列化器,且重写了create方法处理关联数据创建:
from rest_framework import serializers from .models import OrdersDj, AdsDj class AdsDjSerializer(serializers.ModelSerializer): class Meta: model = AdsDj fields = ['title', 'content', 'position'] # 替换为实际广告表字段 class OrdersDjSerializer(serializers.ModelSerializer): ads = AdsDjSerializer(many=True) # 字段名需和前端传的键前缀完全一致 class Meta: model = OrdersDj fields = ['order_no', 'amount', 'creator', 'ads'] # 替换为实际订单表字段 def create(self, validated_data): ads_data = validated_data.pop('ads') # 先创建订单主表数据 order = OrdersDj.objects.create(**validated_data) # 批量创建关联广告数据 AdsDj.objects.bulk_create([AdsDj(order=order, **ad) for ad in ads_data]) return order
内容的提问来源于stack exchange,提问作者kakakakakakakk
相关产品推荐
相关产品推荐

