Django的Querydict奇怪的行为:将POST字典串成单个键 [英] Django's Querydict bizarre behavior: bunches POST dictionary into a single key

查看:183
本文介绍了Django的Querydict奇怪的行为:将POST字典串成单个键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在django中使用测试客户端时遇到一个非常奇怪的行为。

I'm experiencing a really bizarre behavior when using the test client in django.

我正在使用 POST 将数据发送到我的django应用程序。我通常从iPhone应用程序和/或测试HTML表单中完成。在服务器端,这是我如何处理它:

I'm using a POST to send data to my django app. I usually do this from an iPhone app and/or a test html form. On the server side, this is how I handle it:

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

该打印语句看起来像你所期望的,即post请求中的每个参数都变成字典中的一个键:

That print statement looks like what you would expect, i.e. each parameter in the post request is turned into a key in the dictionary:

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

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

然而,我开始使用Django的测试客户端编写一些测试,无论我尝试什么,在POST请求中发送的POST参数被聚合到 QueryDict 中的单个键中。允许我用一些代码来说明:

However, I started writing some tests using Django's test client, and no matter what I try, the dictionary of POST parameters I send in the post request get bunched into a single key in the QueryDict. Allow me to illustrate with some code:

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

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',
        )

服务器端的相同打印语句显示字典中不可思议的字典分组:

The same print statement on the server side shows the inexplicable grouping of the dictionary into a string:

POST: QueryDict: {u'{"amzn_locale":"com"}': [u'']}>,

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

If I set data to an actual dictionary, same thing

data = {"amzn_locale": "com"}

设置request._raw_post_data不会更改任何内容。也不会改变

Setting the request._raw_post_data doesn't change anything. Nor does changing

content_type='application/json'

任何帮助将不胜感激。从这个stackoverflow问题看来,我不是第一个遇到这个
iphone Json POST请求到Django服务器在QueryDict中创建QueryDict

Any help would be much appreciated. From this stackoverflow question it seems like I'm not the first one to run into this iphone Json POST request to Django server creates QueryDict within QueryDict

推荐答案

p>问题是你提供了一个content_type。因为你这样做,客户端期待一个urlencoded字符串,如

The problem is that you're supplying a content_type. Since you did so, the client is expecting a urlencoded string like

"username=hi&password=there&this_is_the_login_form=1"

而不是像

{'username': 'hi', 'password': 'there', 'this_is_the_login_form': 1}

如果你删除content_type kwarg,你会很好。

If you remove the content_type kwarg you'll be fine.

编辑:事实证明,测试客户端将寻找如果您传递除 MULTIPART_CONTENT 之外的任何content_type,则会使用网址编码字符串 - content_type仅用于确定用于编码该url编码字符串的字符集。这是此处记录的文档。相关位:

As it turns out, the test client will look for a url-encoded string if you pass in any content_type other than MULTIPART_CONTENT - the content_type will only be used to figure out what charset to use to encode that url-encoded string. This is documented here. The relevant bit reads:


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

If you provide content_type (e.g., text/xml for an XML payload), the contents of data will be sent as-is in the POST request, using content_type in the HTTP Content-Type header.

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

If you don't provide a value for content_type, the values in data will be transmitted with a content type of multipart/form-data. In this case, the key-value pairs in data will be encoded as a multipart message and used to create the POST data payload.

这篇关于Django的Querydict奇怪的行为:将POST字典串成单个键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆