不要使用json.dumps对某些字符串进行引号处理

1 投票
4 回答
1669 浏览
提问于 2025-04-18 01:59

我正在为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.dumps会把"handlerFunction"加上引号,这不是我想要的。我希望handlerFunction不带引号,这样在JavaScript中它就会被当作一个函数来执行,而不是一个字符串。

我该如何告诉json.dumps不要给某些字符串加引号呢?

4 个回答

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}'
0

json.dumps 这个函数不能提供这样的功能,Python 也做不到,因为这不是一个有效的 JSON 字符串。你应该在 JavaScript 中尝试去掉引号。

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

我原本希望自定义一个 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

现在我可以像这样创建我想要转成 JSON 的字典:{'event': function(handler)},这样它就能正确编码了。

虽然看起来不太好,但确实能用。

撰写回答