Django测试中User.last_login未按预期填充取值为None问题
Django测试中登录后
user.last_login为None的原因及修复 问题根因
- 最核心的错误是创建用户时调用了
User.objects.create()直接传入明文密码:Django 内置User模型的create()方法不会对密码做哈希加密,数据库中存储的是传入的原始明文字符串。当调用auth_client.login()时,Django认证后端会将传入的明文密码做哈希运算后,和数据库中存储的密码值做比对,二者完全不匹配,登录实际是失败的,自然不会触发登录成功后更新last_login字段的逻辑。 - 你可以直接打印
self.auth_client.login()的返回值验证:登录成功该方法返回True,当前代码场景下因为密码校验不通过,返回值一定是False。 - 代码存在一处笔误:
print(user.last_login).行尾多了多余的英文句号,会直接触发语法错误,导致测试无法正常运行。
修复步骤
- 将创建用户的方法替换为Django提供的专用方法
create_user(),该方法会自动对传入的明文密码做哈希处理,保证认证流程正常:
from django.contrib.auth import get_user_model from django.test import TestCase, Client User = get_user_model() class TestModels(TestCase): @classmethod def setUpTestData(cls): # 替换create为create_user,自动处理密码哈希 cls.user = User.objects.create_user( username="testUser", password="testPassword" ) cls.auth_client = Client() # 可选:加断言提前确认登录结果,避免后续逻辑无效 login_success = cls.auth_client.login(username="testUser", password="testPassword") assert login_success is True def test_user_last_login(self): user = User.objects.get(id=self.user.id) # 拉取最新数据 print(user.last_login) # 修复笔误,删掉行尾多余的点 self.assertIsNotNone(user.last_login)
补充说明
Django默认的last_login字段在用户首次创建时初始值就是None,只有用户认证登录成功后,内置的信号处理器才会自动将该字段更新为当前登录时间,只要登录流程正常执行,重新查询数据库就能拿到正确的时间值。
内容的提问来源于stack exchange,提问作者mincom
相关产品推荐
相关产品推荐

