Можем ли мы использовать API, связанные с python, в шаблонах Django? - PullRequest
0 голосов
/ 27 мая 2020

Я новичок в Django и, следовательно, не знаю об этом досконально. Итак, я столкнулся с несколькими ошибками в Django.

В настоящее время я пытаюсь напечатать тип переменной из файла Django template html следующим образом:

<center><h2>The type of feature list report for version {%type(version)%} is<h2></center>

Для вышеуказанного я получаю следующую ошибку:

Invalid block tag on line 9: 'type(version)'. Did you forget to register or load this tag?

Так что здесь не так? Как мы можем использовать API, связанные с python (например, type (), strip (), get (), et c) из файлов шаблонов html? Я думаю, что внутри {% ....%} мы можем использовать оценки, относящиеся к python. Я прав?

Пожалуйста, осветите это.

Ответы [ 3 ]

1 голос
/ 27 мая 2020

Как уже говорилось, это не философия DTL, но некоторые функции, которые преобразуют ввод, реализованы как фильтры .

Кроме того, вы можете написать свои собственные фильтры и поддержать " type "фильтр будет очень простым:

from django import template
from typing import Any

register = template.Library()

def filter_type(value: Any) -> str:
    return str(type(value))

register.filter('type', filter_type)

Подробнее см. документацию .

Подход Jinja и DTL явно превосходит неявный: вместо слепой поддержки любая функция python со всеми ее опасностями, вы должны явно разрешить или реализовать ее.

1 голос
/ 27 мая 2020

Запуск произвольного кода Python в шаблоне Django намеренно отключен. Помимо соображений безопасности, причина в том, что бизнес-логи c вашего проекта должна быть отделена от уровня представления. Это часть хорошего дизайна приложения.

Есть три основных способа вызвать операцию из шаблона Django.

  1. Передать функцию и вызвать ее.
  2. Используйте шаблонный фильтр, настраиваемый или встроенный.
  3. Используйте тег шаблона, настраиваемый или встроенный.

Передайте функцию и вызовите ее.

Вызов переданной функции из шаблона Django является стандартным. Однако здесь есть два предостережения.

  1. Функция должна возвращать значение, которое может быть строкой или может быть приведено к строке. (В противном случае в шаблоне ничего не будет напечатано.)
  2. Функция не должна иметь никаких обязательных аргументов.

Наиболее распространенный вариант использования - это вычисленное значение или геттер, например

class Page(models.Model):
    title = models.CharField()

    def get_title(self):
        return self.title
<h1>{{ page.get_title }}</h1>

Шаблонные фильтры

См. ответ Мелвина для примера шаблонных фильтров.

Шаблонные фильтры работают со значением. Так что это идеально подходит для функции Python, такой как type().

Теги шаблона

Отредактировано: см. Комментарий Мелвина.

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

Вот пример из двух шаблонных тегов, которые я часто включаю в проект в debug.py.

import pprint
from django import template

register = template.Library()
pp = pprint.PrettyPrinter(indent=4, width=120)


@register.simple_tag(takes_context=True)
def print_context(context):
    pp.pprint(context)
    return ""


@register.simple_tag()
def print_thing(thing):
    pp.pprint(thing)
    return ""

Я могу использовать print_context для печати текущего контекста в терминале и print_thing для печати чего-либо.

{% load debug %}
{% print_context %}

{% print_thing 'print this string' %}

Вы можете создать тег шаблона, который будет делать все, что может делать стандартная функция Python. Это связано с тем, что тег шаблона по существу вызывает создаваемую вами функцию.

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

0 голосов
/ 27 мая 2020

Вы можете создать класс, который включает тип, поэтому вы можете вызвать тип, например: variable.type, или вы можете отправить данные типа из контроллера. Если вам нужно сделать логи реактивного программирования c в интерфейсе, я бы посоветовал вам использовать Vue, React или Angular.

...