Django中如何测试需用户认证的视图?登录后访问仍返回302
问题根因
你测试时拿到302状态码,核心是测试创建用户的逻辑不符合Django认证系统的要求:
- 你在
setUp中使用User.objects.create()直接传入明文password参数的写法,会将明文密码直接存入数据库,不会生成Django认证系统要求的密码哈希值。而Django登录校验逻辑,会对用户提交的登录密码做哈希计算后,和数据库存储的哈希值做比对——因为你之前存储的是未处理的明文,比对永远不匹配,client.login()自然无法完成认证,最终被login_required装饰器重定向到登录页,返回302状态。 - 非核心的潜在问题:你在路由中定义的
settings路径没有尾斜杠,如果项目开启了APPEND_SLASH配置,偶发会出现路径匹配偏差,但这不是当前302的主要诱因。
修正方案
1. 调整测试用户创建逻辑
创建合法的Django测试用户,必须使用User.objects.create_user()方法,该方法会自动对传入的密码做哈希处理,生成可通过认证校验的合法凭据。
2. 补全测试覆盖场景
修正后的完整测试代码如下:
from django.test import TestCase from django.contrib.auth.models import User class TestViews(TestCase): def setUp(self): # 正确创建测试用户,自动完成密码哈希处理 self.user = User.objects.create_user( username="testUser", password="testPassword", ) def test_authenticated_user_access_settings(self): # 登录系统后访问设置页 self.client.login(username="testUser", password="testPassword") response = self.client.get("/settings") # 校验访问权限、状态码、渲染模板 self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "project/settings.html") def test_unauthenticated_user_redirect_to_login(self): # 覆盖未登录访问的重定向逻辑 response = self.client.get("/settings") # 校验是否正常重定向到登录页面 self.assertEqual(response.status_code, 302) self.assertRedirects(response, f"/login/?next=/settings/")
注:Django内置的
TestCase已经自动初始化了测试Client实例,不需要手动创建Client()对象,直接使用self.client即可完成请求构造,减少冗余代码。
额外排查提示
如果修正用户创建逻辑后依然存在重定向问题,可以检查两个配置项:
- 项目
settings.py中LOGIN_URL的配置是否和实际登录页面路径匹配 - 路由中
settings路径的定义是否和测试请求的路径完全一致(比如是否遗漏尾斜杠)
内容的提问来源于stack exchange,提问作者mincom
相关产品推荐
相关产品推荐

