Django DRF写入嵌套关联数据时报catalog_products必填错误如何解决
问题原因&修复方案
1. 核心报错原因:请求字段和序列化器声明不匹配
你在序列化器中声明的嵌套字段名为catalog_products,但POST请求中提交的嵌套字段名为pricing_list,序列化器找不到必填的catalog_products字段,直接触发缺失必填项报错。
注意:字段上设置的
source='catalogproducts_set'仅作用于序列化输出阶段,用于关联ORM反向查询集,反序列化输入时默认匹配序列化器声明的字段名。
2. 其他潜在错误
- 序列化器
create方法逻辑错误:- 你尝试从
validated_data中popid字段,但序列化器的fields配置中没有声明id作为输入字段,validated_data中不会存在该键,运行到此处会直接抛KeyError - 获取client对象的代码末尾多了逗号,
client = User.objects.get(id=client_id),会将client转为元组,存入外键字段时会报错 - 遍历
validated_data写入关联表的逻辑错误,嵌套的商品数据是存在validated_data的对应嵌套字段键下,不是直接遍历整个validated_data
- 你尝试从
- 字段拼写错误:请求中
to_quantiy拼写有误,应为to_quantity,如果模型/子序列化器中字段是正确拼写,后续会触发字段不存在报错 - Viewset重写冗余:你重写的create方法中
if serialized_data.is_valid(raise_exception=True)后的判断完全冗余,raise_exception=True参数会在校验失败时直接抛出异常,不会走到后续判断逻辑
修复代码示例
(1)调整请求体
{ "client": 2, "catalog_products": [ { "from_quantity": "101", "to_quantity": "34", "price": "1000" }, { "from_quantity": "10", "to_quantity": "501", "price": "2000" } ] }
如果要保留请求中的pricing_list字段名,可修改序列化器字段声明:
pricing_list = CatalogProductsSerializer(source='catalogproducts_set', many=True)
(2)修复CatalogSerializer
class CatalogSerializer(serializers.ModelSerializer): catalog_products = CatalogProductsSerializer(source='catalogproducts_set', many=True) class Meta: model = Catalog fields = ['client', 'catalog_products', 'created_datetime', 'is_active'] # 自动填充的字段设为只读,不需要前端传入 read_only_fields = ['created_by', 'created_datetime', 'is_active'] def create(self, validated_data): # 取出嵌套的关联数据 catalog_products = validated_data.pop('catalog_products') # 写入主表数据 catalog_obj = Catalog.objects.create( **validated_data, created_by=self.context['user'], is_active=True ) # 批量写入关联表数据 for product_data in catalog_products: CatalogProducts.objects.create(catalog=catalog_obj, **product_data) return catalog_obj
(3)简化Viewset
你当前的业务逻辑不需要自定义create方法,直接用DRF ModelViewSet默认实现即可:
class CatalogViewset(viewsets.ModelViewSet): queryset = Catalog.objects.all() serializer_class = CatalogSerializer permission_classes = [] authentication_classes = []
额外注意:确保
CatalogProductsSerializer的字段配置包含你传入的from_quantity、to_quantity、price三个字段,没有其他必填的输入字段。
内容的提问来源于stack exchange,提问作者Atif Shafi
相关产品推荐
相关产品推荐

