Django模板中的@register.filter vs @register.simple_tag vs @ register.tag vs @register.inclusion_tag

4dc9hkyq  于 2023-07-01  发布在  Go
关注(0)|答案(1)|浏览(127)

下面是关于@register.filter的文档:
自定义过滤器是接受一个或两个参数的Python函数:

  • 变量的值(输入)-不一定是字符串。
  • 参数的值-这可以有一个默认值,也可以完全忽略。

并且,文档在下面提到了@register.simple_tag:
这个函数是django.template.Library的一个方法,它接受一个可以接受任意数量参数的函数,将其 Package 在一个render函数中,并将上面提到的其他必要的位注册到模板系统中。
而且,文档只在下面提到了@register.tag
最后,将标记注册到模块的Library示例中,如上面编写自定义模板标记中所述。
而且,文档在下面提到了@register.inclusion_tag:
另一种常见的模板标记类型是通过呈现另一个模板来显示某些数据的类型。例如,Django的管理界面使用自定义模板标签来显示“添加/更改”表单页面底部的按钮。这些按钮看起来总是一样的,但是链接目标会根据正在编辑的对象而变化--所以它们是使用填充有当前对象细节的小模板的完美案例。
但是,我不明白它们是什么样的,那么Django模板中的@register.filter@register.simple_tag@register.tag@register.inclusion_tag之间有什么区别?

vqlkdk9b

vqlkdk9b1#

@register.filter:

  • 可以将数据返回到Django模板。
  • 的函数可以从模板标记中获取值。
  • 的函数必须有一个或两个参数。* 如果它有零个或两个以上的参数,则存在错误。
  • 不能有takes_context参数。
  • 不适用于as参数。

@register.simple_tag:

  • 可以将数据返回到Django模板。
  • 的函数可以从模板标记中获取值。
  • 可以有takes_context参数。
  • 的函数必须有context作为第一个参数,如果takes_context=True被设置为@register.simple_tag,否则会出现错误。* 第一个参数名称必须是context,否则会出现错误。
  • 使用as参数。

@register.tag:

  • 应该从基于Node类的对象返回str类型值到Django模板,否则会出现错误。
  • 的函数可以从模板标记中获取令牌。
  • 不能有takes_context参数。
  • 的函数必须有parser作为第一个参数,token作为第二个参数(其他名称也可以),否则会出错。
  • 不适用于as参数。

@register.inclusion_tag:

  • 可以将数据返回到其他Django模板,但不能返回到同一个Django模板,因为有错误。
  • 的函数可以从模板标记中获取值。
  • 可以有takes_context参数。
  • 的函数必须有context作为第一个参数,如果takes_context=True被设置为@register.inclusion_tag,否则有一个错误。* 第一个参数名称必须是context,否则会出现错误。
  • 不适用于as参数。

<@register.filter>

例如,从person_view()index.html返回字典,如下所示:

# "views.py"

from django.shortcuts import render

def person_view(request):                # Dictionary
    return render(request, 'index.html', {'name':'John', 'age': 36})

然后,将name传递到person_filter(),如下所示:

# "index.html"

{% load custom_tags %}

{{ name | person }}

然后,将nameperson_filter()返回到index.html,如下所示:

# "custom_tags.py"

from django.template import Library

register = Library()

@register.filter(name="person")
def person_filter(name):
    return name

然后,将显示以下内容:

John

接下来,将nameage传递给person_filter(),如下所示:

# "index.html"

{% load custom_tags %}

{{ name | person:age }}

然后,将nameageperson_filter()返回到index.html,如下所示:

# "custom_tags.py"

from django.template import Library

register = Library()

@register.filter(name="person")
def person_filter(name, age):
    return f'{name} {age}'

然后,将显示以下内容:

John 36

<@register.simple_tag>

例如,从person_view()index.html返回字典,如下所示:

# "views.py"

from django.shortcuts import render

def person_view(request):                # Dictionary
    return render(request, 'index.html', {'name':'John', 'age': 36})

然后,将nameage"Good Person"传递给person_tag(),如下所示:

# "index.html"

{% load custom_tags %}

{% person name age "Good Person" %}

然后,将person_tag()中的nameageextra_info返回到index.html,如下所示:

# "custom_tags.py"

from django.template import Library

register = Library()

@register.simple_tag(name="person")
def person_tag(name, age, extra_info):
    return f'{name} {age} {extra_info}'

然后,将显示以下内容:

John 36 Good Person

接下来,将takes_context=True设置为@register.simple_tag,然后对于person_tag(),我们不需要nameage参数,然后必须将context作为第一个参数,如下图所示。* 如果第一个参数名不是context,则会出现错误:

# "custom_tags.py"
                                    # Here
@register.simple_tag(name="person", takes_context=True)
def person_tag(context, extra_info):
    return f"{context['name']} {context['age']} {extra_info}"

然后,只传递"Good Person"person_tag(),如下所示:

# "index.html"

{% person "Good Person" %}

然后,将显示以下内容:

John 36 Good Person

实际上,您仍然可以将nameageindex.html传递到person_tag(),如下所示:

# "index.html"

{% person name age "Good Person" %}

但是,person_tag()还需要2个参数,如下所示。* nameage参数可以使用其他名称:

# "custom_tags.py"

@register.simple_tag(name="person", takes_context=True)
def person_tag(context, name, age, extra_info):
    # ...                 ↑    ↑

接下来,使用as参数存储从person_tag()person_info的返回值,然后显示如下所示。* 不显示带有as参数的标记:

# "index.html"

{% person "Good Person" as person_info %}
{{ person_info }}

然后,将显示以下内容:

John 36 Good Person

最后在person_tag()中,设置context['extra_info'],然后返回一个空字符串到index.html,如下所示:

# "custom_tags.py"

@register.simple_tag(name="person", takes_context=True)
def person_tag(context, extra_info):
    context['extra_info'] = extra_info
    return ""

然后显示nameageextra_info,如下所示:

# "index.html"

{% person "Good Person" %}
{{ name }} {{ age }} {{ extra_info }}

然后,将显示以下内容:

John 36 Good Person

<@register.tag>

例如,从person_view()index.html返回字典,如下所示:

# "views.py"

from django.shortcuts import render

def person_view(request):                # Dictionary
    return render(request, 'index.html', {'name':'John', 'age': 36})

然后,将nameage"Good Person"传递给person_tag(),如下所示:

# "index.html"

{% load custom_tags %}

{% person name age "Good Person" %}

然后从person_tag()返回PersonNode(),它将从render()返回4个令牌到index.html,如下所示。* 第一个令牌是标签名称person,第二个令牌是name,第三个令牌是age,第四个令牌是"Good Person"@register.tag不能有takes_context参数和@register.tag 's函数的第一个参数必须是parser,第二个参数必须是token(其他名字也可以),否则会出现错误:

# "custom_tags.py"

from django.template import Library, Node

register = Library()

@register.tag(name="person")
def person_tag(parser, token):
    token0, token1, token2, token3 = token.split_contents()
    return PersonNode(token0, token1, token2, token3)

class PersonNode(Node):
    def __init__(self, token0, token1, token2, token3):
        self.token0 = token0
        self.token1 = token1
        self.token2 = token2
        self.token3 = token3

    def render(self, context):
        return f'{self.token0} {self.token1} {self.token2} {self.token3}'

然后,将显示以下内容:

person name age "Good Person"

并且,下面的代码返回第一个令牌,第二个和第三个令牌分别获得的实际nameage值,以及第四个没有双引号的令牌。* template.Variable("key.dot.notation").resolve(dict)可以从一个带有关键点符号的字典中获取值,你可以看到我的答案解释template.Variable("key.dot.notation").resolve(dict)

# "custom_tags.py"

@register.tag(name="person")
def person_tag(parser, token):
    token0, token1, token2, token3 = token.split_contents()
    return PersonNode(token0, token1, token2, token3)

class PersonNode(Node):
    def __init__(self, token0, token1, token2, token3):
        self.token0 = token0
        self.token1 = token1
        self.token2 = token2
        self.token3 = token3

    def render(self, context):
        name = template.Variable(self.token1).resolve(context)
        age = template.Variable(self.token2).resolve(context)
        extra_info = self.token3.replace('"', '')
        return f'{self.token0} {name} {age} {extra_info}'

然后,将显示以下内容:

person John 36 Good Person

下面的代码从contextGood Person返回nameage的值:

# "custom_tags.py"

@register.tag(name="person")
def person_tag(parser, token):
    token0, token1, token2, token3 = token.split_contents()
    return PersonNode()

class PersonNode(Node):
    def render(self, context):
        return f"{context['name']} {context['age']} Good Person"

然后,将显示以下内容:

John 36 Good Person

render()中,设置context['extra_info'],然后向index.html返回一个空字符串,如下所示:

# "custom_tags.py"

@register.tag(name="person")
def person_tag(parser, token):
    return PersonNode()

class PersonNode(Node):
    def render(self, context):
        context['extra_info'] = "Good Person"
        return ""

然后显示nameageextra_info,如下所示:

# "index.html"

{% person %}
{{ name }} {{ age }} {{ extra_info }}

然后,将显示以下内容:

John 36 Good Person

另外,我们还可以创建一个comment标签来注解带有parser参数和@register.tag的单词,如下所示:

# "custom_tags.py"

@register.tag(name='comm')
def comment_tag(parser, token):
    parser.skip_past('endcomm')
    return CommentNode()

class CommentNode(Node):
    def render(self, context):
        return ""

然后,用注解标记{% comm %}{% endcomm %}包围单词,以不显示单词,如下所示:

# "index.html"

{% comm %}This is a comment.{% endcomm %}

<@register.inclusion_tag>

例如,从person_view()index.html返回字典,如下所示:

# "views.py"

from django.shortcuts import render

def person_view(request):                # Dictionary
    return render(request, 'index.html', {'name':'John', 'age': 36})

然后,将nameage"Good Person"传递给person_tag(),如下所示:

# "index.html"

{% load custom_tags %}

{% person name age "Good Person" %}

然后,返回一个从person_tag()result.html的字典,如下所示:

# "custom_tags.py"

from django.template import Library

register = Library()

@register.inclusion_tag(name='person', filename='result.html')
def person_tag(name, age, extra_info):
    return {'n': name, 'a': age, 'ei': extra_info} # Dictionary

然后在result.html中显示naei,如下所示:

# "result.html"

{{ n }} {{ a }} {{ ei }}

然后,将显示以下内容:

John 36 Good Person

请注意,下面的nameageextra_info不能在result.html中显示,因为它们没有从person_tag()返回到result.html

# "result.html"

{{ name }} {{ age }} {{ extra_info }}

接下来,将takes_context=True设置为@register.inclusion_tag,那么对于person_tag(),我们不需要nameage参数,那么必须将context(字典)作为第一个参数,然后设置context['extra_info'],如下所示。* 如果第一个参数名不是context,则会出现错误:

# "custom_tags.py"

@register.inclusion_tag(
    name='person', 
    filename='result.html', 
    takes_context=True
)
def person_tag(context, extra_info):
    context['extra_info'] = extra_info
    return context

然后,只传递"Good Person"person_tag(),如下所示:

# "index.html"

{% person "Good Person" %}

然后在result.html中显示nameageextra_info,如下所示:

# "result.html"

{{ name }} {{ age }} {{ extra_info }}

然后,将显示以下内容:

John 36 Good Person

实际上,您仍然可以将nameageindex.html传递到person_tag(),如下所示:

# "index.html"

{% person name age "Good Person" %}

但是,person_tag()还需要2个参数,如下所示。* nameage参数可以使用其他名称:

# "custom_tags.py"

@register.inclusion_tag(
    name='person', 
    filename='result.html', 
    takes_context=True
)
def person_tag(context, name, age, extra_info):
    # ...                 ↑    ↑

最后,从person_tag()result.html返回一个空字典,如下所示:

# "custom_tags.py"

@register.inclusion_tag(
    name='person', 
    filename='result.html', 
    takes_context=True
)
def person_tag(context, extra_info):
    context['extra_info'] = extra_info
    return {} # Dictionary

然后在index.html中显示nameageextra_info,如下所示:

# "index.html"

{% person "Good Person" %}
{{ name }} {{ age }} {{ extra_info }}

然后,将显示以下内容:

John 36 Good Person

相关问题