DRF一对一关联双模型的更新API报错求助
问题解决:DRF一对一关联模型同时更新的错误修复
错误根源
你遇到的核心问题是自定义的update方法被错误地写在了UserSerializer的Meta类内部,DRF无法识别这个方法,因此仍然使用默认的序列化器更新逻辑——而默认逻辑不支持可写嵌套字段,导致触发报错。
修正步骤及代码
1. 调整UserProfile序列化器
将自动维护的created_time和updated_time设为只读字段,避免更新时传入无效数据:
class UserProfileCrudSerializer(serializers.ModelSerializer): class Meta: model = UserProfile fields = ('location', 'created_time', 'updated_time') read_only_fields = ('created_time', 'updated_time')
2. 修正UserSerializer的update方法位置
把自定义的update方法从Meta类内部移到UserSerializer的顶层,确保DRF能执行这个自定义逻辑:
class UserSerializer(serializers.ModelSerializer): profile = UserProfileCrudSerializer(source='userprofile', many=False) class Meta: model = User fields = ('username', 'email', 'first_name', 'last_name', 'profile') # 移到Serializer类顶层的update方法 def update(self, instance, validated_data): # 取出嵌套的userprofile数据 userprofile_data = validated_data.pop('userprofile', {}) userprofile_instance = instance.userprofile # 更新UserProfile(仅当有数据时执行) if userprofile_data: profile_serializer = UserProfileCrudSerializer( userprofile_instance, data=userprofile_data, partial=True # 支持部分更新(适配PATCH请求) ) profile_serializer.is_valid(raise_exception=True) profile_serializer.save() # 更新User本身 instance = super().update(instance, validated_data) return instance
3. 关于删除逻辑
由于UserProfile和User是一对一关联且设置了on_delete=models.CASCADE,删除User时,对应的UserProfile会被自动级联删除。如果需要单独删除UserProfile但保留User,可以单独编写视图处理,但通常业务场景下删除用户会同步删除其关联的profile。
验证
修改后,发送PATCH请求更新profile.location字段时,DRF会执行自定义的update方法,同时更新User和UserProfile模型,不会再触发原错误。
内容的提问来源于stack exchange,提问作者Bluebear
相关产品推荐
相关产品推荐

