在Django中测试请求参数(" +"表现不同)

时间:2015-04-17 15:51:06

标签: python django

我有一个Django View,它使用查询参数进行一些内容过滤。像这样:

/page/?filter=one+and+two
/page/?filter=one,or,two

我注意到Django将+转换为空格(request.GET.get('filter')返回one and two),我就可以了。我只需要调整我在View中使用的split()函数。

可是...

当我尝试测试此视图时,我打电话给:

from django.test import Client
client = Client()
client.get('/page/', {'filter': 'one+and+two'})

request.GET.get('filter')返回one+and+two:加号并且没有空格。这是为什么?

我想Client().get()模仿浏览器的行为,所以我想了解的是为什么调用client.get('/page/', {'filter': 'one+and+two'})与浏览/page/?filter=one+and+two不一样。 出于测试目的,我认为它应该是相同的,在这两种情况下,视图都应该为过滤器获得一致的值:使用+或使用空格。

我没有得到的是为什么有两种不同的行为。

2 个答案:

答案 0 :(得分:12)

查询字符串中的加号是空格的正常和正确编码。这是一件历史文物; form value encoding for URLs与编码URL中的其他元素的差别很小。

Django负责将查询字符串解码回键值对;该解码包括解码URL百分比编码,其中+被解码为空格。

使用测试客户端时,您传入未编码的数据,因此您可以使用:

client.get('/page/', {'filter': 'one and two'})

然后将其编码为查询字符串,并在尝试访问参数时再次进行解码。

答案 1 :(得分:3)

这是因为测试客户端(实际上是RequestFactory)对您的数据运行django.utils.http.urlencode,导致filter=one%2Band%2Btwo。同样,如果您使用{'filter': 'one and two'},它将转换为filter=one%20and%20two,并会以空格进入您的视图。

如果你真的绝对必须在你的查询字符串中加入优点,我相信可以手动覆盖查询字符串,例如:client.get('/page/', QUERY_STRING='filter=one+and+two'),但在我看来这似乎是不必要和丑陋的。< / p>