使用Python simplejson返回预生成的json

fri*_*ism 5 python django json simplejson geodjango

我有一个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')
Run Code Online (Sandbox Code Playgroud)

问题是,simplejson认为a.area.geojson作为一个简单的字符串,即使它是美丽的预先生成的JSON.这可以通过eval()"区域字符串" 在客户端中轻松修复,但我想做到这一点.我可以告诉simplejson一个特定的字符串已经是json并且应该按原样使用(而不是作为简单的字符串返回)?或者还有另一种解决方法吗?

更新 只是为了澄清,这是当前返回的json:

{
    "id": 95,
    "name": "Roskilde",
    "area": "{ \"type\": \"MultiPolygon\", \"coordinates\": [ [ [ [ 12.078701, 55.649927 ], ... ] ] ] }"
}
Run Code Online (Sandbox Code Playgroud)

挑战是让"area"成为json字典而不是简单的字符串.

Ofr*_*viv 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)
Run Code Online (Sandbox Code Playgroud)

在您看来,您使用:

simplejson.dumps(..., cls=SkipJSONEncoder)
Run Code Online (Sandbox Code Playgroud)

如果你有一个更简洁的方法来测试某些东西已经是JSON,使用它(我的方式 - 寻找以'{'开头并以'}结尾的字符串是丑陋的).


Eri*_*arr 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')
Run Code Online (Sandbox Code Playgroud)