如何获取JS文件以从数据库中提取数据

时间:2019-03-14 18:43:14

标签: javascript django sqlite templates django-models

我是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文件吗?

谢谢

3 个答案:

答案 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而不是letconst,因为这是在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 }};
....