使用Python simplejson 返回预生成的JSON

5 投票
2 回答
1113 浏览
提问于 2025-04-15 17:47

我有一个GeoDjango模型对象,想把它转成json格式。在我的视图里,我是这样做的:

lat = float(request.GET.get('lat'))
lng = float(request.GET.get('lng'))
a = Authority.objects.get(area__contains=Point(lng, lat))
if a:
    return HttpResponse(simplejson.dumps({'name': a.name, 
                                          'area': a.area.geojson,
                                          'id': a.id}), 
                        mimetype='application/json')

问题是,simplejson把a.area.geojson当成了一个普通字符串,尽管它其实是一个漂亮的预生成json。这在客户端可以通过用eval()来处理这个字符串来轻松解决,但我想要更规范的做法。有没有办法告诉simplejson,某个特定的字符串已经是json格式,应该直接使用,而不是当作普通字符串返回?或者有没有其他的解决办法?

更新
为了更清楚,这里是目前返回的json:

{
    "id": 95,
    "name": "Roskilde",
    "area": "{ \"type\": \"MultiPolygon\", \"coordinates\": [ [ [ [ 12.078701, 55.649927 ], ... ] ] ] }"
}

挑战在于让“area”成为一个json字典,而不是一个普通字符串。

2 个回答

5

我觉得一个比较简单的方法是扩展 JSONEncoder,创建一个编码器,它可以检测给定的对象是否已经是 JSON 格式。如果是的话,就直接返回这个对象。如果不是,就用普通的 JSONEncoder 来进行编码。

class SkipJSONEncoder(simplejson.JSONEncoder):
     def default(self, obj):
         if isinstance(obj, str) and (obj[0]=='{') and (obj[-1]=='}'): 
             return obj
         return simplejson.JSONEncoder.default(self, obj)

然后在你的视图中,你可以这样使用:

simplejson.dumps(..., cls=SkipJSONEncoder)

如果你有更好的方法来检查某个东西是否已经是 JSON 格式,使用它(我这种方法 - 检查字符串是否以 '{' 开头并以 '}' 结尾,实在是太丑了)。

2

作者修改后更新:

你能这样做吗:

lat = float(request.GET.get('lat'))
lng = float(request.GET.get('lng'))
a = Authority.objects.get(area__contains=Point(lng, lat))
if a:
    json = simplejson.dumps({'name': a.name, 
                             'area': "{replaceme}",
                             'id': a.id}), 
    return HttpResponse(json.replace('"{replaceme}"', a.area.geojson),
                        mimetype='application/json')

撰写回答