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

DRF中Django ManyToManyField字段categories提交后为空如何解决?

DRF多对多字段空返回修复方案

问题原因

  1. 序列化器未显式声明categories多对多字段的写入权限,配合depth=1配置时,DRF会默认将关联字段设为只读,POST提交的分类ID列表不会被序列化器处理
  2. 多对多字段需要指定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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 03:36:09