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

DRF如何实现序列化器创建时接收ID、返回时输出序列化用户对象

DRF ModelSerializer 同字段写入传ID、返回用户对象的实现方案

方案1:拆分读写字段(DRF官方推荐写法)

核心思路:利用DRF字段的read_only、write_only属性,拆分两个字段分别处理读写逻辑,通过source参数映射到同一个模型字段。
首先定义返回用户基础信息的序列化器:

class UserBasicSerializer(serializers.ModelSerializer):
    class Meta:
        model = User # 替换为你项目的用户模型类
        fields = ('id', 'username')

修改你的业务序列化器:

class InitiateDialogSerializer(ModelSerializer):
    initiator = ListUserViewSerializer(read_only=True)
    # 读字段:序列化返回时输出用户对象
    answerer = UserBasicSerializer(read_only=True)
    # 写字段:仅接收用户ID,写入时映射到answerer字段
    answerer_id = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.all(),
        write_only=True,
        source='answerer'
    )

    class Meta:
        model = Dialog
        fields = ('answerer', 'answerer_id', 'id', 'initiator')
        read_only_fields = ('id', 'initiator')

    def create(self, validated_data):
        validated_data['initiator'] = self.context['request'].user
        return super().create(validated_data)

使用说明:

  • 创建数据时前端传入answerer_id字段,值为数字类型的用户ID即可
  • 接口返回结果仅包含answerer字段,值为带id、username属性的用户对象,不会返回answerer_id字段

方案2:重写序列化方法(字段名统一)

如果你希望读写都用answerer作为字段名,不需要额外加_id后缀,可以重写to_representation方法修改序列化输出逻辑:

class InitiateDialogSerializer(ModelSerializer):
    initiator = ListUserViewSerializer(read_only=True)
    # 写入时接收用户ID,自动校验用户是否存在
    answerer = serializers.PrimaryKeyRelatedField(queryset=User.objects.all())

    class Meta:
        model = Dialog
        fields = ('answerer', 'id', 'initiator')
        read_only_fields = ('id', 'initiator')

    def create(self, validated_data):
        validated_data['initiator'] = self.context['request'].user
        return super().create(validated_data)
    
    # 重写输出逻辑,把answerer转为序列化后的用户对象
    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['answerer'] = UserBasicSerializer(instance.answerer).data
        return data

使用说明:

  • 创建数据时前端直接传入answerer字段,值为数字类型的用户ID即可
  • 接口返回的answerer字段自动转为带id、username的用户对象,前后端字段名完全统一

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:36:03