不要使用json.dumps对某些字符串进行引号处理
我正在为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)}
,这样它就能正确编码了。
虽然看起来不太好,但确实能用。