Django的Querydict奇怪的行为:将POST字典串成一个单独的键

And*_*res 5 python django rest post

在django中使用测试客户端时,我遇到了一种非常奇怪的行为.

我正在使用a POST将数据发送到我的django应用程序.我通常是从iPhone应用程序和/或测试html表单执行此操作.在服务器端,这是我处理它的方式:

def handle_query(request):
   print request
   q = con.QueryLog()
   q.ID = request.POST.get('ID', '')
   q.device = request.POST.get('device-model', '')
   ....
Run Code Online (Sandbox Code Playgroud)

那个print语句看起来像你期望的那样,即post请求中的每个参数都变成了字典中的一个键:

POST:QueryDict:{u'app-version':[u'3.0'],u'server-version':[u'v3d0'],

但是,我开始使用Django的测试客户端编写一些测试,无论我尝试什么,我在post请求中发送的POST参数字典都会聚集在一起QueryDict.请允许我用一些代码来说明:

class SearchTest(TestCase):def setUp(self):pass

def test_search(self):
    request = HttpRequest()
    data = '{"amzn_locale": "com"}'
    # request._raw_post_data = data
    resp = self.client.post(
        '/is/', 
        data=data,
        content_type='application/x-www-form-urlencoded',
        # content_type='application/json',
        )
Run Code Online (Sandbox Code Playgroud)

服务器端的相同print语句显示字典无法解释为字符串:

POST: QueryDict: {u'{"amzn_locale":"com"}': [u'']}>,
Run Code Online (Sandbox Code Playgroud)

如果我将数据设置为实际字典,同样的事情

data = {"amzn_locale": "com"}
Run Code Online (Sandbox Code Playgroud)

设置request._raw_post_data不会改变任何内容.改变也没有

content_type='application/json'
Run Code Online (Sandbox Code Playgroud)

任何帮助将非常感激.从这个stackoverflow问题看起来我似乎不是第一个遇到这个 iphone的Json POST请求到Django服务器在QueryDict中创建QueryDict

mel*_*ath 7

问题是你提供的是content_type.既然你这样做了,那么客户端就像是一个urlencoded字符串

"username=hi&password=there&this_is_the_login_form=1"
Run Code Online (Sandbox Code Playgroud)

而不是像这样的字典

{'username': 'hi', 'password': 'there', 'this_is_the_login_form': 1}
Run Code Online (Sandbox Code Playgroud)

如果你删除content_type kwarg,你会没事的.

编辑:事实证明,如果传入除MULTIPART_CONTENT之外的任何content_type,测试客户端将查找URL编码的字符串- content_type将仅用于确定用于编码该url编码字符串的字符集.这在此处记录.相关位读取:

如果您提供content_type(例如,XML有效负载的text/xml),则将使用HTTP Content-Type标头中的content_type在POST请求中按原样发送数据内容.

如果没有为content_type提供值,则数据中的值将以内容类型multipart/form-data传输.在这种情况下,数据中的键值对将被编码为多部分消息,并用于创建POST数据有效负载.