使用Django DRF APIView更新STUser失败,求正确实现及序列化器解惑
如何用APIView正确实现Django REST Framework的用户更新?
咱们先拆解下你现有代码里的问题,这也是导致你要么碰到“用户已存在”提示、要么意外创建新用户的核心原因:
- 你创建序列化器时用了
serializeddata = UserSerializer(data=request.data)——这种写法是告诉DRF要创建新对象,所以序列化器会触发所有创建时的唯一约束校验(比如用户名、邮箱这类字段),自然会抛出“用户已存在”的错误; - 你直接用
user.__dict__.update(**data)更新用户属性,这种方式非常不安全:会绕过模型字段的验证逻辑,还可能覆盖模型内部的私有属性,绝对不推荐。
下面给你一个完全基于APIView的正确实现方案,不用依赖通用视图:
from rest_framework.response import Response from rest_framework import status from django.shortcuts import get_object_or_404 def put(self, request, *args, **kwargs): # 保留你原有的权限校验逻辑 authorization = UserSuitsPermissions().superuser(request.user) userpk = kwargs.get('pk', 0) user = get_object_or_404(STUser, pk=userpk) if not authorization: # 注意request.user是用户对象,直接取id即可,不用['id'] if request.user.id == user.id: authorization = True if authorization: # 关键:把要更新的user实例传给序列化器,而非只传data # partial=True表示支持部分字段更新(可选,若允许用户只修改部分信息则保留) serializer = UserSerializer(user, data=request.data, partial=True) serializer.is_valid(raise_exception=True) # 用serializer.save()完成更新,DRF会自动处理验证与保存逻辑 updated_user = serializer.save() return Response(UserSerializer(updated_user).data, status=status.HTTP_200_OK) return Response(status=status.HTTP_401_UNAUTHORIZED)
再来说你提到的那行Stack Overflow代码:serializer = self.serializer_class(request.user, data=request.data, partial=True)
这行代码和你的需求直接相关,它的核心逻辑正是你之前代码缺失的:
- 第一个参数传入现有用户实例:告诉序列化器这是更新操作而非创建,这样就不会触发创建时的唯一校验,只会执行更新场景下的验证规则;
partial=True:允许接口接受部分字段的更新请求(比如用户只改邮箱不改用户名);- 依赖
serializer.save()完成更新,而非手动操作模型属性,这是DRF规范的更新方式,能保证数据安全与逻辑合规。
内容的提问来源于stack exchange,提问作者user9487981
相关产品推荐
相关产品推荐

