簡體   English   中英

如何獲取JS文件以從數據庫中提取數據

[英]How to get JS file to pull data from database

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

謝謝

您可以將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>

您還可以將上下文中的數據(從后端傳遞到模板的數據)存儲在包含的腳本可訪問的變量中。 因此,例如,如果從您的角度來看有一個上下文

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中解析它

執行此操作的標准方法是創建一個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的文件中(了解有關在docs中創建自定義過濾器的更多信息: https : myapp_tags.py 標簽/ )。

在模板中,您需要先加載過濾器,然后才能使用它:

{% 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/zh-CN/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 }};
....

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM