Django PUT接口的serializer如何忽略缺失字段实现部分更新
实现部分字段更新的两种方案
DRF的ModelSerializer默认会校验所有声明在fields中且未显式设置required=False的字段,PUT请求默认执行全量更新校验,要实现仅更新传入字段、保留原有字段值的需求,可选择以下任意方案:
方案1:视图层添加partial=True参数(最小改动,推荐)
仅需要修改序列化器实例化逻辑,新增partial=True参数即可告知序列化器仅校验请求传入的字段,未传入字段自动跳过校验、保留数据库原有值:
def put(self, request): user_uuid = get_uuid_from_request(request) user_obj = User.objects.get(pk=user_uuid) # 新增partial=True开启部分更新支持 serializer = UpdateUserSerializer(user_obj, data=request.data, partial=True) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_200_OK) else: return Response(dict(error=serializer.errors, user_msg=generic_error_message), status=status.HTTP_400_BAD_REQUEST)
该方案适合当前PUT接口专门用于支持部分字段更新的场景,无需修改序列化器定义。
方案2:序列化器层显式设置字段非必填
如果希望UpdateUserSerializer在所有调用场景下都支持不传全部字段,可以给每个字段显式设置required=False,同时可匹配模型字段的约束配置其他参数:
class UpdateUserSerializer(serializers.ModelSerializer): given_name = serializers.CharField(required=False) middle_name = serializers.CharField(required=False, allow_blank=True, allow_null=True) family_name = serializers.CharField(required=False) birthdate = serializers.DateField(required=False, allow_null=True) class Meta: model = User fields = ('given_name', 'middle_name', 'family_name', 'birthdate')
注意事项
- 字段参数需和数据库模型字段的约束对齐,比如模型中
birthdate设置了null=True才能在序列化器中配置allow_null=True,避免保存时触发数据库层面的报错 - 若遵循RESTful接口规范,部分更新本身属于PATCH请求的语义,也可将部分更新逻辑迁移到单独的PATCH接口,保留PUT接口全量更新的逻辑,可根据业务需求选择。
内容的提问来源于stack exchange,提问作者user12314098
相关产品推荐
相关产品推荐

