不要使用json.dumps来引用一些字符串

时间:2014-04-09 08:47:52

标签: python json

我正在为jqGrid开发一个Django包装器(是的,另一个,现有的不适合我的需要)。在我的包装器中,我正在生成初始化网格的Javascript代码。此代码如下所示:

$('#my-grid').jqGrid({
    "option1": 12,
    "option2": "option",
    "eventHandler": handlerFunction
});

由于我在Python中生成此代码,因此我创建了一个类似的字典:

options = {"option1": 12, "option2": "option", "eventHandler": "handlerFunction"}
然后我按照json.dumps这样使用:

js_code = "${'#my-grid').jqGrid(%s);" % json.dumps(options)

问题是json.dump在"handlerFunction"附近加上引号,这不是我想要的。我希望handlerFunction不被引用,因此它在JavaScript中被评估为函数,而不是字符串。

如何告诉json.dumps不引用某些字符串?

4 个答案:

答案 0 :(得分:2)

我希望自定义JsonEncoder可以解决这个问题,但是没有 - 编码器返回的对象会通过正常的编码序列,因此会引用字符串。

所以我必须做点别的事情:

首先我定义了以下功能:

def function(name):
    return '@@' + name + '@@'

然后我创建了一个JSON编码函数,而不是json.dumps:

def my_dumps(obj, *args, **kwargs):
    s = json.dumps(obj, *args, **kwargs)
    s = s.replace('"@@', '')
    s = s.replace('@@"', '')
    return s

现在,我可以像这样创建我要成为jsoned的词典:{'event': function(handler)}并且它将被正确编码。

不漂亮,但确实有效。

答案 1 :(得分:0)

那不会奏效。解决方案不是在Python和JavaScript中混合使用逻辑。这是一种方法:将所有JavaScript移动到模板并仅将数据传递给它:

def some_view(...):
    grid_options = {
        "option1": 12,
        "option2": "option",
    }
    return render(request, {'grid_options': json.dumps(grid_options)})

在视图中:

var gridOptions = {{ grid_options }};

$('#my-grid').jqGrid($.extend(gridOptions, {
    "eventHandler": handlerFunction
});

答案 2 :(得分:0)

json.dumps不能提供这样的功能,Python也不能,因为它不是有效的json字符串。你应该尝试在JS中取消引用它。

答案 3 :(得分:0)

除了@ zmbq的回答:my_dumps为你包装了密钥。

key_wrap_seq = '@@'

def wrap_key(name):
    return key_wrap_seq + name + key_wrap_seq

def wrap_obj_keys(obj):
    if type(obj) is dict:
        return {wrap_key(k): wrap_obj_keys(obj[k]) for k in obj}
    elif type(obj) is list:
        return [wrap_obj_keys(x) for x in obj]
    else:
        return obj

def my_dumps(obj, *args, **kwargs):
    obj_wrapped = wrap_obj_keys(obj)
    s = json.dumps(obj_wrapped, *args, **kwargs)
    s = s.replace('"'+key_wrap_seq, '')
    s = s.replace(key_wrap_seq+'"', '')
    return s

结果:

>>> obj = {"name": "john", "age": 22}
>>> my_dumps(obj)
... '{name: "john", age: 22}'