我是Django的新手,正在从事一个简单的项目,该项目涉及拥有用户提交的表单,然后创建一个仪表板页面,该页面提供一些漂亮的可视化图表,汇总了用户输入的数据。我正在为仪表板页面使用免费模板。创造性的蒂姆将其称为“黑色仪表盘”。
在我的HTML模板中,有以下
<canvas id="chartBig1"></canvas>
我相信这引用了JS文件中有关要显示的图表的信息
下面是我认为html引用的JS文件的片段
var myChart = new Chart(ctxGreen, {
type: 'line',
data: data,
options: gradientChartOptionsConfigurationWithTooltipGreen
});
var chart_labels = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
var chart_data = [100, 70, 90, 70, 85, 60, 75, 60, 90, 80, 110, 100];
var ctx = document.getElementById("chartBig1").getContext('2d');
数据是静态的。使用我使用models.py保存的数据显示这些图的最佳方法是什么?我可以直接将数据拉入JS文件吗?
谢谢
答案 0 :(得分:0)
您可以将JS代码段移至html模板并将其删除到文件中,然后按以下方式呈现数据:
# template.html
<body>
...
<script>
var myChart = new Chart(ctxGreen, {
type: 'line',
data: data,
options: gradientChartOptionsConfigurationWithTooltipGreen
});
var chart_labels = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
var chart_data = [
{% for instance in queryset %}
{{ instance.data_point }}{% if not forloop.last %}, {% endif %}
{% endfor %}
];
var ctx = document.getElementById("chartBig1").getContext('2d');
</script>
</body>
答案 1 :(得分:0)
您还可以将上下文中的数据(从后端传递到模板的数据)存储在包含的脚本可访问的变量中。因此,例如,如果您从视图中获得的上下文是
context = { 'name': name }
您可以在模板模板中的脚本标签内
<script>var randomJsVariableName = "{{ name }}";</script>
,您应该能够在外部js文件中访问该文件,只要该文件包含在模板标签中,并且在脚本标签后带有变量即可,即
<script>var randomJsVariableName = "{{ name }}";</script>
<script src="externalJsFile.js"></script>
还请记住,如果在您的主要可继承模板中,如果您有一个js块,则您正在使用的模板中的js使用block标签。另外,我在这里使用var
而不是let
或const
,因为这是在html模板中,而且我不知道您是否以某种方式设置了babel而且我相信IE或Edge不喜欢let和const
编辑: @thebjorn在说这将返回一个typeof字符串时是正确的。您可以将其分配给变量而不使用引号,而只需获取要传递的原始类型,或者可以传递字符串并将其解析为js
答案 2 :(得分:0)
执行此操作的标准方法是创建一个Django模板过滤器,该过滤器会将上下文变量转换为json(根据设计,该变量是有效的有效javascript值文字):
from django.import template
from django.utils.safestring import mark_safe
import json
register = template.Library
@register.filter
def jsonval(val):
"""Output ``val`` as a (json) value suitable for assigning to variables in
javascript::
var js_var = {{ python_var|jsonval }};
"""
return mark_safe(json.dumps(val, sort_keys=True, indent=4))
这需要放置在应用程序的templatetags文件夹中,通常位于名为myapp_tags.py
的文件中(有关在文档中创建自定义过滤器的更多信息:https://docs.djangoproject.com/en/2.1/howto/custom-template-tags/)。
在模板中,您需要先加载过滤器,然后再使用它:
{% load myapp_tags %}
....
var chart_data = {{ chart_data|jsonval }};
....
在您看来,您需要确保chart_data上下文变量是json可序列化的-即。仅包含列表,字典,字符串,数字,布尔值和无(即,没有Django查询集等)。 有关json的文档包含有关解决此限制的方法的信息,请参见https://docs.python.org/3/library/json.html-在“扩展JSONEncoder”下;这可能需要在js端执行类似的解码步骤:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_the_reviver_parameter,尽管这会使您的过滤器标签更加复杂:
@register.simple_tag
def json_setup():
return """
var my_reviver = function (key, val) {
if (typeof val === 'string' && val.startsWith("@date:")) {
var dateval = val.slice("@date:".length);
return new Date(Date.parse(dateval));
}
return val; // else
};
"""
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.date):
return "@date:" + obj.isoformat() # e.g. "@date:2019-03-15"
if isinstance(obj, decimal.Decimal):
return float(obj)
# ..etc..
# Let the base class default method raise the TypeError
return json.JSONEncoder.default(self, obj)
@register.filter
def jsonval(val):
return mark_safe('JSON.parse("%s", my_reviver)' % json.dumps(val, cls=MyEncoder, sort_keys=True))
和您的模板:
{% load myapp_tags %}
{% json_setup %}
....
var chart_data = {{ chart_data|jsonval }};
....