Как получить файл JS для извлечения данных из базы данных - PullRequest
1 голос
/ 14 марта 2019

Я новичок в Django и работаю над простым проектом, который включает в себя создание формы, которую пользователь отправляет, а затем страницу панели инструментов, которая дает несколько хороших визуальных диаграмм, суммирующих вводимые пользователем данные. Я использую бесплатный шаблон для страницы панели инструментов. Творческий Тим называет его черной панелью.

В моем HTML-шаблоне есть следующее

<canvas id="chartBig1"></canvas>

это, я полагаю, справочная информация в файле JS о диаграмме для отображения

ниже приведен фрагмент файла JS, который, я думаю, содержит ссылки html

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 голосов
/ 14 марта 2019

вы также можете хранить данные из своего контекста, которые вы передаете в шаблон из бэкэнда, в переменную, которая доступна для включенного скрипта. так что если у вас есть, например, контекст с вашей точки зрения, который

context = { 'name': name }

в вашем шаблоне внутри тегов скрипта вы можете сделать

<script>var randomJsVariableName = "{{ name }}";</script>

и вы сможете получить к нему доступ во внешнем js-файле, если он включен в ваш шаблон после тега script с переменной в нем, т.е.

<script>var randomJsVariableName = "{{ name }}";</script>
<script src="externalJsFile.js"></script>

также помните, что если в вашем основном наследуемом шаблоне, если у вас есть блок для js, используйте теги блока для вашего js в шаблоне, над которым вы сейчас работаете. Также в качестве примечания я использую var здесь вместо let или const, потому что это в html-шаблоне, и я не знаю, настроен ли у вас babel каким-либо образом, и я верю, что IE или Edge не нравится пусть и const

EDIT: @thebjorn правильно говорит, что это вернет строку typeof. Вы можете присвоить его переменной без использования кавычек и просто получить исходный тип, который вы передаете, или вы можете передать строку и проанализировать ее в js

0 голосов
/ 15 марта 2019

Стандартный способ сделать это - создать шаблонный фильтр 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-serializable - т.е. содержит только списки, слова, строки, числа, логические значения и None (т. е. нет наборов запросов 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 }};
....
0 голосов
/ 14 марта 2019

Вы можете переместить фрагмент 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>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...