我有一个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
不一样。 出于测试目的,我认为它应该是相同的,在这两种情况下,视图都应该为过滤器获得一致的值:使用+
或使用空格。
我没有得到的是为什么有两种不同的行为。
答案 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>