2013-10-06 5 views
2

Я создаю веб-приложение на платформе Google App Engine, в котором используется webapp2, который использует WebOb. Я хотел бы получить POST некоторые данные в формате JSON, включая вложенные массивы и словари. Например .:Google App Engine: Python: WebOb: Как получить данные POST в формате JSON?

$.post('/addvendor', {'vendor': {'name': 'test', 'description': 'a good company', 'tags':['foo', 'bar']}}, function(data){console.log(data)}, 'application/json') 

Однако на стороне сервера, данные поступают в виде плоского «MultiDict» объект, а не что-либо как исходного вложенного объекта JSON, который я POST ред. Например:

>>> print self.request.params.items() 
[(u'vendor[name]', u'test'), (u'vendor[description]', u'a good company'), (u'vendor[tags][]', u'foo'), (u'vendor[tags][]', u'bar')] 

Этот объект очень трудно разобрать. В моем коде сервера есть способ получить те же данные в стандартном формате JSON или, по крайней мере, эквивалент Python с использованием вложенных словарей и массивов на сервере, чтобы я мог легко манипулировать и анализировать данные?

+0

Я нашел такой же вопрос: http://stackoverflow.com/questions/9058233/how-to-convert-a-multidict-to-nested-dictionary К сожалению, ответ на этот вопрос мне бесполезен, потому что я могу Включить пакет formencode в среду движка Google. Я думаю, что я могу переключиться на Heroku и использовать node.js. – jayhendren

+0

$ .post - jquery? вы используете python 2.7. *? Можете ли вы тогда не делать что-то вроде: 'vendor = json.loads (self.request.get ('vendor'))' Вам нужно импортировать json с 'import json' – HMR

ответ

2

(обновлено с помощью jayhendren) Вы должны использовать $ .ajax и вручную установить contentType = 'application/json; charset = utf-8 ', потому что $ .post использует default "application/x-www-form-urlencoded;" Тип содержимого. Кроме того, необходимо вручную кодировать данные в JSON-строку с JSON.stringify:

$.ajax({url:'/addvendor', 
     type: 'post', 
     data:JSON.stringify({'vendor': {'name': 'test', 'description': 'a good company', 'tags':['foo', 'bar']}}), 
     contentType:'application/json; charset=utf-8', 
     dataType: "json", 
     success:function(data){console.log(data)}}) 

... 

print json.loads(self.request.body) 
+0

Этот ответ, я думаю, показывает отсутствие понимания интерфейс webob. Вот значение 'self.request.body':' vendor% 5Bname% 5D = test & vendor% 5Bdescription% 5D = a + good + компания и поставщик% 5Btags% 5D% 5B% 5D = foo & vendor% 5Btags% 5D% 5B% 5D = bar' И вот что произойдет, если я попытаюсь декодировать это как json oject: 'ValueError: объект JSON не может быть декодирован' – jayhendren

+1

Извините, забыли про одну важную вещь: параметр данных jquery.ajax должен быть простым объектом или строкой (http : //api.jquery.com/jQuery.ajax/). Если вы передаете только объект, jquery преобразует его в строку запроса, которую вы видите. Чтобы отправить JSON-закодированные данные, вы должны вручную создать JSON-строку с помощью JSON.stringify() – Denisigo

+0

. Хм, спасибо, это начинает туда добраться. Я по-прежнему получаю ошибку «без JSON-объекта, которая может быть расшифрована», но по крайней мере у меня есть закодированная строка, которая представляет объект JSON, а не мультидиск для работы. Это намного лучше, чем передача прямого объекта JSON в '$ .post'. Тем не менее, я использовал другие API, которые не требовали, чтобы я «стягивал» объект JSON до того, как он отправил его на сервер. Например, при использовании backbone.js я мог бы интерпретировать данные «POST» как объект JSON на сервере, не требуя, чтобы клиент «стягивал» его или его сервер декодировал. – jayhendren

1

использование json.dumps (yourdata) не забыл изменить заголовок Content-Type для применения/JSON

headers = { 
"Content-Type": "application/json" 
} 
session.post(<url>, data=json.dumps(yourdata)) 
+0

Спасибо за ваш ответ, но я не думаю, что вы внимательно прочитали вопрос или другой ответ. Мне не нужно отправлять запрос POST с сервера, мне нужно отправить его с помощью javascript AJAX-вызова от клиента. Кроме того, этот вопрос уже решен, как вы можете видеть из другого ответа, который я принял, и потока комментариев. – jayhendren

+0

@jayhendren +1, потому что для webapp2/GAE важно понять, что 'request.body' работает только для JSON, когда' request.content_type == 'application/json''. Сегодня я сделал изменения в своих тестах, и внезапно внутри обработчика мой «request.body» был закодирован в URL. Мне просто пришлось добавить 'content-type = application/json' в POST, и все было в порядке. –