Передача объекта JSON через POST с использованием Python - PullRequest
16 голосов
/ 30 июня 2010

Я пытаюсь опубликовать объект JSON через POST.Я пытаюсь сделать это следующим образом:

import json, urllib, urllib2

filename = 'test.json'
race_id = 2530
f = open(filename, 'r')
fdata = json.loads(f.read())
f.close()

prefix = 'localhost:8000'

count = 0
for points in fdata['positions'].iteritems():
    print '--' + str(count) + '--------'
    url = 'http://'+prefix+'/api/points'
    parameters = {'point_data': json.dumps(points), 'race_id': race_id}
    data = urllib.urlencode(parameters)
    print data
    request = urllib2.Request(url, data)
    response = urllib2.urlopen(request)
    count += 1
    break;

print 'Finished adding points'

Затем данные получаются на другом конце (я использую Google App Engine) с:

point_data = json.load(self.request.get('point_data'))

Но яполучить следующую ошибку:

ERROR    2010-06-30 15:08:05,367
__init__.py:391] 'unicode' object has no attribute 'read' Traceback (most
recent call last):   File
"/home/ian/workspace/google_appengine/google/appengine/ext/webapp/__init__.py",
line 513, in __call__
    handler.post(*groups)   File "/home/ian/workspace/codebase/track_builder/geo-api.py",
line 276, in post
    point_data = json.load(self.request.get('point_data'))
File
"/home/ian/workspace/google_appengine/lib/django/django/utils/simplejson/__init__.py",
line 208, in load
    return cls(encoding=encoding, **kw).decode(fp.read()) AttributeError: 'unicode' object has
no attribute 'read' INFO    
2010-06-30 15:08:05,376
dev_appserver.py:3266] "POST
/api/points HTTP/1.1" 500 -

Есть идеи, как это исправить?

РЕДАКТИРОВАТЬ: В соответствии с запросом здесь приведен пример точек:

(u'1276859700',
{
    u'24': {
        u'tempc': u'-22.7',
        u'gpsq': u'1',
        u'altm': u'65527',
        u'hd': u'112',
        u'hdop': u'0.93',
        u'bton': u'0',
        u'maxv': u'20.15',
        u'idit': u'1',
        u'satc': u'10',
        u'minv': u'20.15',
        u'lat': u'35.271993',
        u'btusr': u'0',
        u'lng': u'-121.845353',
        u'knots': u'7'
    },
    u'11': {
        u'tempc': u'13.0',
        u'gpsq': u'1',
        u'altm': u'65535',
        u'hd': u'130',
        u'hdop': u'0.84',
        u'bton': u'0',
        u'maxv': u'15.96',
        u'idit': u'1',
        u'satc': u'12',
        u'minv': u'15.88',
        u'lat': u'34.877815',
        u'btusr': u'0',
        u'lng': u'-121.386116',
        u'knots': u'8'
    }
}

РЕДАКТИРОВАТЬ 2: Спасибо Дэниелу Роузману и Нику Джонсону, которые оба уловили мою ошибку.Я изменил

point_data = json.loads(self.request.get('point_data'))

Это решило ошибку, но теперь я получаю:

ERROR    2010-06-30 16:07:29,807 __init__.py:391] 'list' object has no attribute 'iteritems'
Traceback (most recent call last):
  File "/home/ian/workspace/google_appengine/google/appengine/ext/webapp/__init__.py", line 513, in __call__
    handler.post(*groups)
  File "/home/ian/workspace/codebase/track_builder/geo-api.py", line 255, in post
    for time, units in point_data.iteritems():
AttributeError: 'list' object has no attribute 'iteritems'
INFO     2010-06-30 16:07:29,816 dev_appserver.py:3266] "POST /api/points HTTP/1.1" 500 -

, что относится к следующему коду:

class TrackPoint(webapp.RequestHandler):
    def post(self):
        point_data = json.loads(self.request.get('point_data'))
        race_id = self.request.get('race_id')
        added = []
        failed = []
        for time, units in point_data.iteritems():
            for unit, data in units.iteritems():
                ...

Есть идеи по этому поводу?

Ответы [ 3 ]

31 голосов
/ 30 июня 2010

Похоже, self.request.get() возвращает объект Unicode, а не объект, подобный файлу.Вы можете попробовать использовать json.loads() вместо json.load().

4 голосов
/ 30 июня 2010

json.load () ожидает объект файла, но self.request.get возвращает значение параметра в виде строки.

Решение простое: используйте json.loads.

Кроме того, бесплатный совет: я предполагаю от имени, что вы связываете свою собственную копию библиотеки JSON.App Engine фактически включает в себя копию simplejson, которую вы можете использовать - просто сделайте:

from django.utils import simplejson
1 голос
/ 06 мая 2011

сначала в js Я узнаю, что объект json должен быть в формате STRING (файл javascript)

// using jquery, json2
var js = {"name":"nguyen","age":"1"};
$.post("/", {'data': JSON.stringify(js)}, function(ret){
        alert(ret);
    });

, затем в gae

from django.utils import simplejson as json

class PesonReq(webapp.RequestHandler):
    def post(self):
        t = json.loads(self.request.POST['data'])
        self.response.out.write(t['name'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...