我正在为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
不引用某些字符串?
答案 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}'