如何检查用户上次登录时间?实现未登录次日更新模型
用户登录时间检查与连续登录中断处理方案
一、如何检查用户的上次登录时间?
Django自带的User模型内置了last_login字段,直接通过用户实例即可获取:
- 在登录信号(如
user_logged_in)中,可通过user.last_login拿到上次登录的datetime对象 - 若要做日期对比,需转成日期格式(剔除时分秒):
user.last_login.date()
二、业务需求实现修正(前一天未登录则重置连续登录天数)
你提供的代码存在几个问题:
UserStatisticStatus.objects.update(day_streak=0)会更新所有用户的连续登录天数,而非当前目标用户- 判断逻辑不准确,业务要求"前一天未登录",应检查上次登录日期是否早于
today - timedelta(days=1)(即昨天及更早未登录) class_completed可能为None(用户从未完成过课程),直接访问class_completed.updated_at会触发报错- 信号装饰器后的函数缩进错误,不符合Python语法规范
修正后的代码如下:
from django.db.models.signals import post_save from django.dispatch import receiver from django.contrib.auth.signals import user_logged_in from django.utils import timezone from datetime import timedelta from .models import ClassAttempt, UserStatisticStatus @receiver(user_logged_in) def user_logged_in_streak(sender, request, user, **kwargs): today = timezone.now().date() # 获取用户最近一次完成的课程记录,处理无记录的情况 class_completed = ClassAttempt.objects.filter( user=user, status='completed' ).order_by('-updated_at').first() # 检查用户前一天是否未登录:上次登录日期 < 昨天 last_login_date = user.last_login.date() if user.last_login else None if last_login_date and last_login_date < today - timedelta(days=1): # 仅重置当前用户的连续登录天数 UserStatisticStatus.objects.filter(user=user).update(day_streak=0) # 可补充:用户无课程完成记录时的处理逻辑 if not class_completed: pass
关键修正点说明:
- 适配
user_logged_in信号的正确参数(该信号直接传递user对象,原代码参数使用有误) - 针对当前用户过滤
UserStatisticStatus,避免批量更新所有用户数据 - 增加
last_login为None的边界处理(新用户首次登录场景) - 修正判断逻辑,准确识别"前一天未登录"的场景
- 处理
class_completed为None的情况,防止触发AttributeError
内容的提问来源于stack exchange,提问作者Riccardo
相关产品推荐
相关产品推荐

