代码之家  ›  专栏  ›  技术社区  ›  friism

使用python simplejson返回预生成的json

  •  5
  • friism  · 技术社区  · 15 年前

    我有一个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() 在区域字符串,但我想做得恰当。我能告诉 普莱斯杰森 特定的字符串已经是JSON,应该按原样使用(而不是作为简单字符串返回)?或者还有其他解决方法吗?

    更新 只是澄清一下,这是当前返回的JSON:

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

    挑战是让“area”成为JSON字典,而不是简单的字符串。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Eric Palakovich Carr    15 年前

    作者编辑后编辑:

    你能这样做吗?

    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')
    
        2
  •  5
  •   Ofri Raviv    15 年前

    我认为最简单的方法是扩展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, 拜托 使用它(我的方法-查找以“”开头、以“”结尾的字符串很难看)。