Django单元测试GET请求重定向至登录页问题求助
Django单元测试登录后仍被重定向的排查与解决
我之前也碰到过一模一样的坑,咱们一步步拆解问题来解决:
1. 先把用户创建和登录的基础步骤做对
你代码里的self.em...没写完,大概率是漏了创建测试用户的关键步骤——如果用户都不存在,登录操作其实是静默失败的,自然会被重定向到登录页。另外要注意:Django的TestCase已经自带了self.client实例,不需要你手动self.client = Client(),手动实例化会导致session不共享,这是很多人踩过的坑。
修正后的setUp方法应该是这样:
def setUp(self): self.username = 'testuser' self.password = 'testpass123' # 先创建合法的测试用户 self.user = User.objects.create_user( username=self.username, password=self.password, email='test@example.com' ) # 用TestCase自带的client登录,并且强制断言登录成功 login_success = self.client.login(username=self.username, password=self.password) self.assertTrue(login_success, "登录失败!请检查用户名和密码是否匹配")
加self.assertTrue很重要,能帮你快速发现登录是否静默失败(比如密码写错了),不会让你在后续排查里走弯路。
2. 检查目标视图的权限控制逻辑
如果你的目标页面用了@login_required装饰器,或者类视图继承了LoginRequiredMixin,那必须确保登录状态有效。如果视图还有额外的权限要求(比如特定用户组、自定义权限),还要给测试用户补上对应的权限:
# 示例:给测试用户添加查看某个模型的权限 from django.contrib.auth.models import Permission permission = Permission.objects.get(codename='view_your_model') self.user.user_permissions.add(permission)
3. 验证请求本身的正确性
- 确认请求的URL拼写完全正确,有没有漏写斜杠、路径是否和
urls.py里的配置一致; - 尽量用
reverse()方法获取URL,避免硬编码出错:from django.urls import reverse response = self.client.get(reverse('your_protected_page_url_name'))
4. 检查settings里的核心中间件
确保你的settings.py里启用了维持登录状态的必备中间件,少了任何一个都可能导致登录状态无法保存:
MIDDLEWARE = [ # ... 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # ... ]
最后给你一个完整的可运行测试示例:
from django.test import TestCase from django.contrib.auth.models import User from django.urls import reverse class SimpleTest(TestCase): def setUp(self): self.username = 'testuser' self.password = 'testpass123' self.user = User.objects.create_user( username=self.username, password=self.password, email='test@example.com' ) # 登录并验证成功 login_success = self.client.login(username=self.username, password=self.password) self.assertTrue(login_success) def test_access_protected_page(self): # 用reverse获取目标页面URL response = self.client.get(reverse('protected_page_name')) # 断言返回200状态码,说明成功访问 self.assertEqual(response.status_code, 200) # 可选:断言页面包含预期内容,确认是目标页面 self.assertContains(response, "欢迎访问受保护页面")
内容的提问来源于stack exchange,提问作者Vishal Raghavan
相关产品推荐
相关产品推荐

