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

DRF update_profile接口更新后首次返回旧数据,如何传递更新后的请求到profile接口

问题根源

你遇到的问题是两个原因叠加导致的:

  • QuerySet.update() 方法是直接对数据库执行SQL更新,不会更新当前请求上下文里已经加载到内存的request.user(也就是你self.get_user()拿到的实例)
  • 你调用self.profile(request)的时候传入的还是原来的请求对象,里面缓存的用户实例还是更新前的旧数据

解决方案

方案1:更新后主动刷新request里的用户实例(最匹配你的需求)

直接修改request对象内缓存的user属性为最新的数据库数据,再传给self.profile方法即可,修改后的update_profile代码如下:

@action(detail=False, methods=['post'], authentication_classes=(JWTAuthentication, SessionAuthentication))
def update_profile(self, request):
    profile_serialize = ProfileSerializer(data=request.data)
    profile_serialize.is_valid(raise_exception=True)

    user_id = self.get_user().pk
    AppUser.objects.filter(pk=user_id).update(**profile_serialize.data)
    # 主动更新request内的user为最新数据
    request.user = AppUser.objects.get(pk=user_id)

    return Response(self.profile(request).data)

方案2:重构代码复用序列化逻辑(更规范,耦合度更低)

不需要二次调用self.profile视图方法,把公共的序列化逻辑抽离出来,更新完成后直接序列化最新的用户实例返回即可:

# 抽离公共的用户资料序列化方法
def get_user_profile_data(self, user):
    return UserSerializer(user, context={"request": self.request}).data

@action(detail=False, methods=['get'], authentication_classes=(JWTAuthentication, SessionAuthentication))
def profile(self, request):
    user = self.get_user()
    if not user:
        raise AuthenticationFailed()
    return Response(
        {"status": 200, "message": "Success", "data": self.get_user_profile_data(user)},
        status=status.HTTP_200_OK)

@action(detail=False, methods=['post'], authentication_classes=(JWTAuthentication, SessionAuthentication))
def update_profile(self, request):
    profile_serialize = ProfileSerializer(data=request.data)
    profile_serialize.is_valid(raise_exception=True)

    user = self.get_user()
    # 直接更新实例属性后保存,会自动同步当前实例的字段值,无需额外查库
    for k, v in profile_serialize.data.items():
        setattr(user, k, v)
    user.save()

    return Response(
        {"status": 200, "message": "Success", "data": self.get_user_profile_data(user)},
        status=status.HTTP_200_OK
    )

方案3:修改profile方法强制每次读库(不推荐,性能略差)

如果你不想修改update逻辑,也可以直接调整profile方法的取数逻辑,每次都从数据库拉取最新数据,不使用内存缓存的用户实例:

@action(detail=False, methods=['get'], authentication_classes=(JWTAuthentication, SessionAuthentication))
def profile(self, request):
    # 每次直接查库拉取最新用户数据,绕过内存缓存
    user = AppUser.objects.filter(pk=self.get_user().pk).first()
    if not user:
        raise AuthenticationFailed()
    return Response(
        {"status": 200, "message": "Success", "data": UserSerializer(user, context={"request": self.request}).data},
        status=status.HTTP_200_OK)

内容的提问来源于stack exchange,提问作者Ankit Chaurasia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:06:01