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

如何用单个Serializer保存Django多模型?Djoser注册报错

解决方案

问题根源

你遇到的ValueError是因为Djoser序列化器在创建用户后,尝试将嵌套字段的字典值直接赋值给CustomUser.userProfile关联属性(该属性要求接收UserProfile实例,而非字典)。这是由于嵌套序列化器的默认逻辑与你自定义的create方法产生了冲突。

方案一:将嵌套字段设为write_only

把userProfile序列化器字段标记为仅用于反序列化(创建数据),这样返回响应时不会处理该字段,避免错误的赋值操作:

CustomUser = get_user_model()

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ['user_guid', 'user_type', 'wallet_balance', 'created_at', 'updated_at']
        read_only_fields = ['user_guid', 'created_at', 'updated_at']

class CustomUserCreateSerializer(DjoserUserCreateSerializer):
    # 添加write_only=True,仅在创建时接收数据
    userProfile = UserProfileSerializer(write_only=True)

    class Meta:
        model = CustomUser
        fields = ['id', 'email', 'password', 'userProfile']
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user_profile_data = validated_data.pop('userProfile')
        user = CustomUser.objects.create_user(**validated_data)
        # 创建关联的UserProfile
        UserProfile.objects.create(user=user, **user_profile_data)
        return user

方案二:重写to_representation手动序列化关联数据

如果需要在返回的响应中包含userProfile信息,可以重写序列化器的to_representation方法,手动处理关联数据的序列化:

CustomUser = get_user_model()

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ['user_guid', 'user_type', 'wallet_balance', 'created_at', 'updated_at']
        read_only_fields = ['user_guid', 'created_at', 'updated_at']

class CustomUserCreateSerializer(DjoserUserCreateSerializer):
    userProfile = UserProfileSerializer()

    class Meta:
        model = CustomUser
        fields = ['id', 'email', 'password', 'userProfile']
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user_profile_data = validated_data.pop('userProfile')
        user = CustomUser.objects.create_user(**validated_data)
        UserProfile.objects.create(user=user, **user_profile_data)
        return user

    def to_representation(self, instance):
        # 先调用父类获取基础序列化数据
        representation = super().to_representation(instance)
        # 手动序列化userProfile并添加到响应数据中
        representation['userProfile'] = UserProfileSerializer(instance.userProfile).data
        return representation

额外优化建议

你的UserProfile模型中wallet_balance字段没有设置默认值,会导致创建用户时如果不传该字段就报错,建议添加默认值:

wallet_balance = models.FloatField(default=0.0)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:26:07