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

DRF:如何通过中间件正确更新继承默认User的Profile模型?

问题分析与解决方案

我一眼就看到问题出在update_or_create的调用方式上——你没给它指定查找匹配的条件,它根本不知道要对应哪个用户的Profile记录!下面一步步帮你修正:

第一步:修正中间件的核心逻辑

你的中间件里,update_or_create的用法完全错了。这个方法需要先传入用于定位现有记录的条件,再通过defaults参数指定要更新的字段。把middleware.py改成这样:

from django.utils import timezone
class UpdateLastActivityMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response
        
    def __call__(self, request):
        response = self.get_response(request)
        # 把更新逻辑放在请求处理完成后执行,更贴合"最后活动时间"的语义
        if request.user.is_authenticated:
            # 正确用法:先指定查找条件,再用defaults传要更新的字段
            Profile.objects.update_or_create(
                user=request.user,  # 核心:绑定当前登录用户
                defaults={'last_activity': timezone.now()}
            )
        return response
    
    # 可以删掉process_view方法,我们把逻辑移到__call__里更合理

关键说明:

  • user=request.user是核心:告诉Django要找当前登录用户对应的Profile,找不到就自动创建一条和该用户绑定的新记录。
  • defaults参数:专门用来存放要更新/设置的字段,避免和查找条件混淆。
  • 移到__call__的响应阶段:不会在视图处理前就执行更新,等请求完成后再更新,更符合业务逻辑。

第二步:可选但强烈推荐的优化——用信号自动生成Profile

为了避免新用户注册后没有Profile记录的情况,建议在models.py里添加Django信号,让User创建时自动生成对应Profile:

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from django.utils import timezone

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    last_activity = models.DateTimeField()  # filled in by middleware
    def __str__(self):
        return str(self.id)

# 新用户创建时自动生成Profile
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance, last_activity=timezone.now())

# 保存User时同步保存Profile
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

这样新用户注册后,系统会自动为他生成Profile,中间件只需要负责更新last_activity字段即可。

验证修改效果

  1. 重启Django服务器
  2. 用已注册用户登录并发送任意请求
  3. 访问你的ProfileList接口,就能看到该用户的Profile记录,且last_activity字段已经被正确更新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:52:52