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

如何测试Django中带有@login_required装饰器的视图?

解决Django带@login_required视图的测试上下文断言问题

问题根源

你遇到的错误是因为测试时实际访问的是登录页面(而非目标视图),导致response.context里没有预期的name键。可能的原因包括:

  • 登录操作未成功执行
  • 请求方法不匹配(比如视图只处理GET,但测试用了POST)
  • reverse用法错误导致路由跳转异常
  • follow=True跟进了重定向,最终响应是登录页而非目标视图

修复步骤

  1. 验证登录是否成功
    client.login()会返回布尔值表示登录状态,在setUp里添加断言确保登录成功,避免因登录失败跳转到登录页:

    def setUp(self):
        self.client = Client()
        # 断言登录成功,否则直接抛出错误
        login_success = self.client.login(username='1', password='Pass@123')
        self.assertTrue(login_success, "登录失败,请检查用户名和密码是否正确")
    
  2. 修正reverse的用法
    reverse需要传入视图的名称字符串(对应urls.py中path的name参数),而非直接传视图函数对象:

    # 假设urls.py中该视图的name是'my_view'
    url = reverse('my_view')
    
  3. 使用正确的请求方法
    如果你的my_view是处理GET请求(通常渲染页面的视图是GET),测试时改用get方法,而非post:

    response = self.client.get(url)
    

    (如果视图确实需要POST,确保请求参数正确,且视图支持POST方法)

  4. 移除不必要的follow=True
    登录成功后访问视图不会触发重定向,follow=True会导致客户端跟进可能的错误重定向,最终拿到的是登录页响应,因此直接移除该参数。

修改后的完整测试代码

from django.test import TestCase, Client
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.contrib.auth.models import User

@login_required
def my_view(request):
    # 补充name变量的定义(原代码中缺失)
    name = "测试名称"
    context={'name':name}
    # 注意:home.html需要加引号
    return render(request, 'home.html', context)

class TestEmployer(TestCase):
    
    def setUp(self):
        self.client = Client()
        # 创建测试用户,避免依赖数据库中已存在的账号
        self.user = User.objects.create_user(username='1', password='Pass@123')
        login_success = self.client.login(username='1', password='Pass@123')
        self.assertTrue(login_success, "登录失败,请检查账号信息")

    def test_list_employer(self):
        # 替换为urls.py中视图对应的name值
        url = reverse('my_view')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertIn('name', response.context)
        # 还可以额外断言name的值是否正确
        self.assertEqual(response.context['name'], "测试名称")

额外注意事项

  • 原视图代码中home.html需要加单/双引号,否则会报语法错误;同时name变量需要提前定义,否则视图运行时会报错。
  • 用User.objects.create_user创建测试用户,能保证测试环境的独立性,不会受数据库现有数据影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 21:23:17