我是Django的新手,因此没有足够的知识。所以我在Django中遇到了一些错误。
当前,我正尝试从Django模板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?
那么这里出了什么问题?我们如何从html模板文件中使用与python相关的api(例如type(),strip(),get()等)?我认为在{%....%}内部,我们可以使用与python相关的评估。我对吗?
请为此点些灯光。
答案 0 :(得分:1)
如上所述,这不是DTL的原理,但是一些转换输入的函数实现为filters。
此外,您可以编写自己的过滤器并支持“类型”过滤器,这将非常简单:
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)
有关详细信息,请参见the documentation。
Jinja和DTL的方法都是显式的,而不是隐式的:与其一味地支持任何python函数带来的所有危险,不如明确地允许它或实现它。
答案 1 :(得分:1)
有意禁用在Django模板中运行任意Python代码。除了安全问题外,原因是您项目的业务逻辑应与表示层分开。这是良好的应用程序设计的一部分。
您可以通过三种主要方法从Django模板调用操作。
从Django模板调用传入的函数是标准的。但是,它有两个警告。
最常见的用例是计算值或吸气剂,例如
class Page(models.Model):
title = models.CharField()
def get_title(self):
return self.title
<h1>{{ page.get_title }}</h1>
有关模板过滤器的示例,请参见Melvyn's answer。
模板过滤器对值进行操作。因此,对于type()
之类的Python函数而言,这是完美的选择。
已编辑:请参阅Melvyn的评论。
简单模板标签的工作方式更像一个函数。它们接受位置和关键字参数,并应再次返回值。在这里,我将不涉及包含标记或高级标记的编译和渲染,但是您可以在Django custom template tag docs中进行了解。
这是我经常在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模板系统的约束,创建设计良好的应用程序,其中业务逻辑位于视图,模型和帮助器中,而不位于模板中。
答案 2 :(得分:0)
您可以创建一个包含类型的类,因此可以像这样调用类型:variable.type
,也可以从控制器发送类型数据。
如果您需要在前端进行反应式编程逻辑,建议您使用Vue,React或Angular。