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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:09:18