如何用单个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
相关产品推荐
相关产品推荐

