我有一个脚本,该脚本接收上载的数据,将其合并在一起,将其转换为绘图(使用Bokeh),然后将其作为JSON导出到目录中。
将来,用户可以点击正确的URL,相应的图作为HTML模板的一部分显示给用户。
我可以生成情节。我可以将其另存为JSON。我可以获取将该URL检索为JSON的URL,但是无法获取要在模板中呈现的JSON图。
我已经了解了Bokeh文档和示例,但是它们似乎都使用了flask应用程序来提供页面。
我认为我走在正确的轨道上,使用views.py查找并返回JSON作为render()
响应的一部分,然后让Bokeh.embed.embed_items()
在模板中完成工作看起来不错,但效果不佳-除了绘图以外,所有内容都会显示。
1)创建图并将其放置在目录中以供以后使用(app / results / 1)
创建plot.py
import os
import json
from django.conf import settings
from bokeh.embed import json_item
from bokeh.plotting import figure
x=[1,2,3,4,5]
y=[0,-1,-2,3,4]
p=figure(title="test_example")
p.line(x, y)
#json_export = json_item(p, "result")
json_export = json_item(p)
with open(os.path.join(settings.RESULTS_DIR,"1", "test.json"), 'w') as fp:
fp.write(json.dumps(json_export))
2)设置网址
urls.py
urlpatterns=[
path('result/<int:pk>', views.resultdetailview, name='result-detail'),
]
3)接受请求,使用pk查找剧情json,并将其全部渲染到适当的模板中。
views.py
def resultdetailview(request, pk):
results=str(pk)
with open(os.path.join(settings.RESULTS_DIR, results, "test.json"), 'r') as fp:
#data=json.load(fp)
data=json.loads(fp.read())
#context={'result':data}
#return render(request, 'app/sandbox_detail.html', context)
return render(request=request,
context={'json_object':data, 'resources':CDN.render()})
注意::如果我改用return JsonResponse(data, safe=False)
,则该网址会成功返回json ...
因此,我认为问题出在模板中。
4)向用户显示奇妙的情节
sandbox_detail.html
<header>
<link rel="stylesheet" href="http://cdn.pydata.org./bokeh/release/bokeh-0.11.1.min.css" type="text/css" >
<script type="text/javascript" src="http://cdn.pydata.org./bokeh/release/bokeh-0.11.1.min.js"> </script>
</header>
<h1> Title: Test </h1>
<div>Test</div>
<body>
<div id="result"></div>
<script>
Bokeh.embed.embed_item({{json_object}}, "result");
</script>
</body>
此模板呈现“结果” div以外的所有内容。
我错过了什么?
答案 0 :(得分:1)
这是我到目前为止看到的:
第一::您正在混合使用两种将绘图json数据注入页面的方法。 根据文档,您可以使用以下两种方法之一进行操作:
1)直接指定div
:
Python: json_data = json.dumps(json_item(p, "myplot"))
JavaScript: Bokeh.embed.embed_item(item);
2)在div
函数中指定embed_item
:
Python: json_data = json.dumps(json_item(p))
JavaScript: Bokeh.embed.embed_item(item, "myplot");
但不是两个都同时出现。这可能是问题吗?
秒:最好不要手工插入Bokeh资源:而是使用CDN.render()或INLINE.render()自动包含脚本所需的全部内容:
import json
from bokeh.resources import CDN
return render(request = request,
template_name = 'app/sandbox_detail.html',
context = { json_object = json.loads(json_string),
resources = CDN.render() } )
sandbox_detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
{{ resources }}
</head>
<body>
<div id="result"></div>
<script>
Bokeh.embed.embed_item({{ json_object }}, "result");
</script>
</body>
</html>
第三手:请确保您在页面中嵌入的内容是json对象而不是字符串(请参见上面的变量命名)
答案 1 :(得分:0)
当您在浏览器的调试工具中调试渲染的模板时,它会有所帮助。
我尝试了一种非常相似的方法,但发现了一个大缺陷:我的浏览器指出找不到None
对象。这是因为python将空值存储为None
,而JavaScript需要一个null
对象。
解决方案?运行None
时,Python已经将null
转换为json.dumps
。为了保持这种方式,请以字符串形式读取json字符串。因此,请使用data=json.loads(fp.read())
代替您的data=fp.read()
。