DRF中Django ManyToManyField字段categories提交后为空如何解决?
DRF多对多字段空返回修复方案
问题原因
- 序列化器未显式声明
categories多对多字段的写入权限,配合depth=1配置时,DRF会默认将关联字段设为只读,POST提交的分类ID列表不会被序列化器处理 - 多对多字段需要指定
many=True属性才能接收数组格式的参数
解决方法
场景1:仅需要返回分类ID
直接在序列化器中显式配置categories字段为可写即可:
# 注意补全你原来写错的序列化器类名 class DesignerProductSerializer(serializers.ModelSerializer): designerproductmedia = DesignerProductMediaSerializer(many=True, read_only=True) user = serializers.PrimaryKeyRelatedField(queryset=Login.objects.all(), many=False) collection = serializers.PrimaryKeyRelatedField(queryset=DesignerCollection.objects.all(), many=False) # 新增categories字段配置 categories = serializers.PrimaryKeyRelatedField( queryset=DesignerCategories.objects.all(), many=True ) user_name = serializers.CharField(source='user.name', read_only=True) user_photo = serializers.CharField(source='user.display_photo', read_only=True) class Meta: model = DesignerProduct fields = ('id', "user", "categories", "collection", 'created_at', 'designerproductmedia', 'title', 'descripton', 'price', 'editions', 'verified', 'user_name', 'user_photo') # 不需要返回关联分类详情的话可以删除depth配置,避免冗余查询 # depth = 1
修改后直接POST提交categories=[1,2,3]即可正常关联,DRF界面也会显示该字段的输入框。
场景2:需要返回分类的详细信息
采用读写分离的字段配置,兼顾写入效率和返回体验:
# 先定义分类的嵌套序列化器 class DesignerCategoriesSerializer(serializers.ModelSerializer): class Meta: model = DesignerCategories # 自行调整需要返回的分类字段 fields = ('id', 'name') class DesignerProductSerializer(serializers.ModelSerializer): designerproductmedia = DesignerProductMediaSerializer(many=True, read_only=True) user = serializers.PrimaryKeyRelatedField(queryset=Login.objects.all(), many=False) collection = serializers.PrimaryKeyRelatedField(queryset=DesignerCollection.objects.all(), many=False) # 读场景:返回分类详情 categories = DesignerCategoriesSerializer(many=True, read_only=True) # 写场景:接收分类ID列表,不参与返回 categories_ids = serializers.PrimaryKeyRelatedField( queryset=DesignerCategories.objects.all(), many=True, write_only=True ) user_name = serializers.CharField(source='user.name', read_only=True) user_photo = serializers.CharField(source='user.display_photo', read_only=True) class Meta: model = DesignerProduct fields = ('id', "user", "categories", "categories_ids", "collection", 'created_at', 'designerproductmedia', 'title', 'descripton', 'price', 'editions', 'verified', 'user_name', 'user_photo') # 重写创建方法绑定分类关联 def create(self, validated_data): categories = validated_data.pop('categories_ids') instance = super().create(validated_data) instance.categories.set(categories) return instance # 重写更新方法支持修改分类 def update(self, instance, validated_data): if 'categories_ids' in validated_data: categories = validated_data.pop('categories_ids') instance.categories.set(categories) return super().update(instance, validated_data)
修改后POST提交categories_ids=[1,2,3]即可,返回结果中categories字段会包含所有关联分类的详细信息。
内容的提问来源于stack exchange,提问作者soubhagya
相关产品推荐
相关产品推荐

