让Python感到困惑,将JSON作为字符串而非文字返回

时间:2013-10-31 22:15:08

标签: python json api flask flask-sqlalchemy

我在RoR中做了一些编码,在Rails中,当我通过API调用返回一个JSON对象时,它返回为

{ "id" : "1", "name" : "Dan" }

然而在Python(使用Flask和Flask-SQLAlchemy)中,当我通过json.dumps或jsonpickle.encode返回JSON对象时,它将返回为

"{ \"id\" : \"1\", \"name\": \"Dan\" }"这似乎非常笨拙,因为它无法在另一端轻松解析(在这种情况下通过iOS应用程序 - Obj-C)。

我在这里缺少什么,如何将其作为JSON文字而不是JSON字符串返回?

这就是我的代码:

people = models.UserRelationships.query.filter_by(user_id=user_id, active=ACTIVE_RECORD)
friends = people.filter_by(friends=YES)

json_object = jsonpickle.encode(friends.first().as_dict(), unpicklable=False, keys=True)
print(json_object)  # this prints here, i.e. { "id" : "1", "name" : "Dan" }

return json_object # this returns "{ \"id\" : \"1\", \"name\": \"Dan\" }" to the browser

4 个答案:

答案 0 :(得分:2)

看起来你在这里使用Django,在这种情况下做类似的事情

from django.utils import simplejson as json
...
return HttpResponse(json.dumps(friends.first().as_dict()))

答案 1 :(得分:2)

您在此理解的缺点是,当您在Python中使用JSON模块时,您不使用JSON对象。根据定义,JSON只是一个匹配某个标准的字符串。

让我们说你有字符串:

friends = '{"name": "Fred", "id": 1}'

如果你想在python中使用这些数据,你需要将它加载到python对象中:

import json
friends_obj = json.loads(friends)

此时friends_obj是一个python词典。

如果你想转换它(或任何其他python字典或列表),那么这就是json.dumps派上用场的地方:

friends_str = json.dumps(friends_obj)
print friends_str
'{"name": "Fred", "id": 1}'

但是,如果我们试图“转储”原始的朋友字符串,你会看到你得到不同的结果:

dumped_str = json.dumps(friends)
print dumped_str
'"{\\"name\\": \\"Fred\\", \\"id\\": 1}"'

这是因为你基本上试图将普通字符串编码为JSON并且它正在转义字符。我希望这有助于理解事物!

干杯

答案 2 :(得分:0)

这几乎总是表明您在某处对数据进行了双重编码。例如:

>>> obj = { "id" : "1", "name" : "Dan" }
>>> j = json.dumps(obj)
>>> jj = json.dumps(j)
>>> print(obj)
{'id': '1', 'name': 'Dan'}
>>> print(j)
{"id": "1", "name": "Dan"}
>>> print(jj)
"{\"id\": \"1\", \"name\": \"Dan\"}"

在这里,jj是一个完全有效的JSON字符串表示 - 但它不是obj的表示,它是字符串j的表示,这是无用的。

通常你不直接这样做;相反,您要么首先使用JSON字符串而不是对象(例如,您是从客户端请求或文本文件中获取的),要么在requests或{jsonpickle等库中调用了某些函数。 {1}}使用已编码的字符串隐式调用json.dumps。但无论哪种方式,它都是同样的问题,使用相同的解决方案:只是不要进行双重编码。

答案 3 :(得分:0)

您应该使用flask.jsonify,它不仅会正确编码,还会相应地设置content-type标题。

people = models.UserRelationships.query.filter_by(user_id=user_id, active=ACTIVE_RECORD)
friends = people.filter_by(friends=YES)

return jsonify(friends.first().as_dict())