Django 的测试客户端 returns 编码不正确 URL
Django's test client returns an improperly encoded URL
我有一个视图应该在用户未登录时尝试访问 /amos
时重定向到 /accounts/login/?next=/amos/
。为了对此进行测试,我使用以下测试:
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 似乎只是一个原始字符串,而自定义函数 returns 是一个正确的 URL 编码字符串。在这种情况下我该怎么办?我应该不对它进行 URL 编码还是 django.test.client
有问题?
编辑:我在 DjangoProject 网站上阅读了之前提出的 bug。据我了解,这似乎是有意为之的行为?也就是说,在 Django 的内部系统中,URLs 没有被编码。想请教有经验的人,谢谢!
如果您查看 Django 的 redirect_to_login
方法,它被像 login_required
这样的装饰器使用,您会发现它将正斜杠视为安全字符并且不对其进行编码。
login_url_parts[4] = querystring.urlencode(safe='/')
您可以在测试中模仿这种行为。但是,我认为最简单的做法是不对字符串进行 url 编码。要测试的重要事情是重定向匿名用户。 Django 中应该已经有测试以确保 url 被正确编码,所以我不确定重复这个是否会有很多收获。
redirect_url = reverse('login') + '?next=/amos/'
对我来说这很有效
self.assertRedirects(response, reverse('login') + '?next=' + urllib.parse.quote_plus('/something/'))
别忘了import urllib
我有一个视图应该在用户未登录时尝试访问 /amos
时重定向到 /accounts/login/?next=/amos/
。为了对此进行测试,我使用以下测试:
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 似乎只是一个原始字符串,而自定义函数 returns 是一个正确的 URL 编码字符串。在这种情况下我该怎么办?我应该不对它进行 URL 编码还是 django.test.client
有问题?
编辑:我在 DjangoProject 网站上阅读了之前提出的 bug。据我了解,这似乎是有意为之的行为?也就是说,在 Django 的内部系统中,URLs 没有被编码。想请教有经验的人,谢谢!
如果您查看 Django 的 redirect_to_login
方法,它被像 login_required
这样的装饰器使用,您会发现它将正斜杠视为安全字符并且不对其进行编码。
login_url_parts[4] = querystring.urlencode(safe='/')
您可以在测试中模仿这种行为。但是,我认为最简单的做法是不对字符串进行 url 编码。要测试的重要事情是重定向匿名用户。 Django 中应该已经有测试以确保 url 被正确编码,所以我不确定重复这个是否会有很多收获。
redirect_url = reverse('login') + '?next=/amos/'
对我来说这很有效
self.assertRedirects(response, reverse('login') + '?next=' + urllib.parse.quote_plus('/something/'))
别忘了import urllib