Skip to main content
 首页 » 编程设计

python之Django 的测试客户端返回编码不正确的 URL

2024年10月24日33EasonJim

当用户尝试访问 /amos 时,我有一个 View 应该重定向到 /accounts/login/?next=/amos/ t 已登录。为了对此进行测试,我使用以下测试:

import urllib 
 
# I actually define this function elsewhere, I placed it here for brevity's sake 
def url_with_querystring(path, **kwargs): 
    return path + '?' + urllib.urlencode(kwargs) 
 
def setUp(self): 
    self.client = Client() 
 
def test_call_view_denies_anonymous(self): 
    target_url = reverse('amos_index') 
    redirect_url = url_with_querystring(reverse('login'), next='/amos/') 
    response = self.client.get(target_url, follow=True) 
    self.assertRedirects(response, redirect_url) 
    response = self.client.post(target_url, follow=True) 
    self.assertRedirects(response, redirect_url) 

self.assertRedirects(response, redirect_url) 发生错误。具体来说,它会引发此错误:

AssertionError: Response redirected to '/accounts/login/?next=/amos/', expected '/accounts/login/?next=%2Famos%2F' 

显然,错误来自 / 不等于 %2F。 response 返回的重定向 URL 似乎只是一个原始字符串,而自定义函数返回一个正确的 URL 编码字符串。在这种情况下我该怎么办?我应该不对它进行 URL 编码还是这是 django.test.client 的问题?

编辑:我读过之前提出的 bug在 DjangoProject 网站上。据我了解,这似乎是有意为之的行为?也就是说,在 Django 的内部系统中,URL 没有被编码。想请教更多有经验的人的一些见解,谢谢!

请您参考如下方法:

如果你看看 Django 的 redirect_to_login login_required 等装饰器使用的方法,您可以看到它将正斜杠视为安全字符并且不对其进行编码。

login_url_parts[4] = querystring.urlencode(safe='/') 

您可以在测试中模仿这种行为。但是,我认为最简单的方法就是不对字符串进行 urlencode。要测试的重要事情是重定向匿名用户。 Django 中应该已经有测试以确保 url 的编码正确,所以我不确定重复此操作是否有很多好处。

redirect_url = reverse('login') + '?next=/amos/'