如何在测试 Django 时禁用 csrf?

how to disable csrf in testing django?

我在使用 csrf 令牌测试视图时遇到问题。

这个代码

class ViewTests(TestCase):
    def test_bets_view(self):
        login_page = self.client.get('/users/login/')
        print(login_page.content)

returns HTML 使用 CSRF 隐藏输入。

还有这件事,我需要和前者比较一下HTML,

expected_html = render_to_response('login.html',
                                   dictionary={'form': LoginForm()})

没有隐藏的 CSRF 输入。所以断言失败。

如何在测试客户端中禁用 CSRF 呈现?

您永远不应该比较完整的 HTML 内容。只需检查功能。如果您需要不惜一切代价禁用 csrf,我猜以下逻辑应该会有所帮助。

在您的 views.py 文件中,添加以下包

from django.views.decorators.csrf import csrf_exempt

然后就在您执行检查的函数定义之前,添加此代码段:

@csrf_exempt

这将禁用csrf 的默认验证。即使您的传入请求具有隐藏的 csrf 令牌,您的服务器功能也会完全忽略它。这应该可以解决禁用 csrf 的问题。

首先,您在测试中获取页面并从中提取 csrf 令牌:

page = self.client.get("/users/login")
token = page.context.get("csrf_token")

然后你使用相同的token来渲染模板并比较:

expected_html = TemplateResponse(
    page.wsgi_request,                                              
    "login.html",                                   
    context={"form": LoginForm(), "csrf_token": token}).render()

assert expected_html.content == page.content

您可以像这样在单元测试中覆盖中间件设置:

from django.test import override_settings

testing_middleware = [ ... anything but csrf middleware goes here ]


class TestWhatever(TestCase)
    @override_settings(MIDDLEWARE=testing_middleware)
    def testSomething():
        # no csrf error will occur 
        self.client.post('/', data={ ... })