Django中的自定义模板标签和过滤器
在本教程中,我们将看看如何在Django中创建自定义模板标签和过滤器。
Django模板语言带有内置的模板标签,如{% if %} ,以及过滤器,如safe 。然而,你可能会发现你需要Django默认没有包含的功能。在这种情况下,你可以使用Python创建过滤器和标签,并使用load 标签来利用它们。
让我们开始吧!
前提条件
要跟上进度,你必须具备以下条件
- 有能力创建一个简单的Django应用程序。
- 安装了Python和Django。
- 一个合适的IDE,如Pycharm、VS Code等。
目标
在本教程结束时,你将能够。
- 理解自定义模板标签和过滤器的使用,以及它们如何工作。
- 创建你的自定义模板标签和过滤器以满足你的需求。
开始学习
你的自定义标签和过滤器必须在一个Django应用程序中。如果你想让你的标签和过滤器在整个项目中使用,你可以创建一个应用来完成这个任务。
按照下面的步骤来创建本教程所需的文件。
- 创建一个名为
Contacts的应用程序,并将其添加到你的INSTALLED_APPS。 - 在你的应用程序中,创建一个叫做
templatetags的目录,与视图、模型等处于同一级别。 - 通过创建一个
__init__.py文件使templatetags目录成为一个 Python 包。 - 创建另一个文件
custom_tags.py来保存你的自定义标签和过滤器。
现在你的应用程序的结构将类似于这样。
.Contact
├── contact
│ ├── admin.py
│ ├── apps.py
│ |
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── templatetags
│ │ └── custom_tags.py
│ ├── tests.py
│ ├── url.py
│ └── views.py
├── Contact
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3
└── manage.py
你可以在templatetags 文件夹中创建尽可能多的模块。然而,你应该注意,使用{% load %} 标签只对特定的模块有效,而不是应用。
为了让我们能够加载我们的自定义模板标签和过滤器,我们需要创建一个Library 实例来在Django模板中注册它们。我们将添加以下几行代码来做到这一点。
from django import template
register = template.Library()
为了加载标签和过滤器,我们将在我们的模板中做以下工作。
{% load custom_tags %}
编写自定义过滤器
过滤器通常被写成{{value|filter}} 或{{value|filter:'arg'}} 。这意味着过滤器在作用于一个值时将会或不会接受一个参数。
考虑一个简单的联系人列表程序,显示联系人和他们的创建时间。
models.py 看起来如下。
from django.db import models
class Contact(models.Model):
name = models.CharField(max_length=50)
date = models.DateField()
该应用程序看起来如下,只需做一点样式设计。

现在让我们创建两个简单的过滤器,将给定名称中的所有字符串、单词的第一个字符大写,同时设置一个颜色。
我们使用@register ,在Django中注册我们的过滤器并给它一个名字。我们的函数需要一个名字作为它的值。
为了使用我们的过滤器,我们在模板中使用行{% load custom_tags %} 。
template_tags/custom_tags.py
# create the register instance by initializing it with the Library instance.
from django import template
register = template.Library()
# An upper function that capitalizes word passed to it. We then register the filter using a suitable name.
@register.filter(name='upper')
def upper(value):
return value.upper()
# An upper function that capitalizes the first letter of the word passed to it. We then register the filter using a suitable name.
@register.filter(name='modify_name')
def modify_name(value):
return value.title()
# An upper function that sets returns a red color. We then register the filter using a suitable name.
@register.filter(name='get_color')
def color(value):
if value:
return "#FF0000"
contact.html
<!-- Loading the custom_tags file to avail our tags and filters -->
{% load custom_tags %}
{% block content %}
{% for contact in contacts %}
<div class="flex-box-container">
<!-- We now use the get_color and upper filters to change color and capitalize the contact name respectively -->
<div style="background-color: {{contact.name|get_color}};"><p >{{contact.name|upper}}</p></div>
<div><b>Created:</b> {{ contact.date }}</div>
</div>
{% endfor %}
{% endblock content %}
最终的视图将如下图所示。

upper 过滤器将联系人的名字大写,而get_color 过滤器则为 div 设置了新的颜色。
同样,你也可以创建你的自定义过滤器,以满足你对模板的任何需求。
你应该检查分配给你的视图的名称。它们应该与@register.filter() 中使用的名称一致。例如,使用color ,而不是get_color ,会导致错误。你可能还需要考虑Django的过滤器的自动转义行为。
编写自定义模板标签
模板标签比过滤器更高级。它们的强大之处在于,它们可以处理任何数据,并使其对任何模板可用,而不管执行的是什么视图。Django提供了两个常用的辅助函数来创建标签。
- 简单标签。
- 包容性标签。
我们将在我们的custom_tags.py 文件中实现这些标签。
简单标签
这些标签接受任意数量的参数,并在一些处理后返回一个结果。简单标签是一个函数,它接受一个或多个参数,将其包装在一个渲染函数中,并在模板系统中注册。
我们将做两个简单标签的例子。我们的第一个简单标签将计算我们拥有的联系人的数量。第二个函数将获得当前日期,格式为d/m/y 。
custom_tags.py 中的代码如下。
import datetime
# Create the register instance by initializing it with the Library instance.
from Django import template
register = template.Library()
# An upper function that capitalizes word passed to it.
@register.filter(name='upper')
def upper(value):
return value.upper()
# An upper function that capitalizes the first letter of the word passed to it.
@register.filter(name='modify_name')
def modify_name(value):
return value.title()
# An upper function that sets returns a red color.
@register.filter(name='get_color')
def color(value):
if value:
return "#FF0000"
# A function that sets returns the number of contacts.
@register.simple_tag(name='my_contacts')
def my_contacts():
return Contact.objects.all().count()
# A function that sets returns the current date.
@register.simple_tag(name='current_date')
def current_date(format):
return datetime.datetime.now().strftime(format)
把HTML改成这样。
<!-- Loading the custom_tags file to avail our tags and filters -->
{% load custom_tags %}
{% block content %}
<!-- Using the my_contacts simple tag -->
<h3>You have {% my_contacts %} contacts</h3>
{% for contact in contacts %}
<div class="flex-box-container">
<!--Using the get_color and upper filters to change color and capitalize the contact name respectively -->
<div style="background-color: {{contact.name|get_color}};"><p >{{contact.name|upper}}</p></div>
<!-- Using the current_date simple tag -->
<div><b>Created:</b> {% current_date "%d/%m/%Y" %} </div>
</div>
{% endfor %}
{% endblock content %}
由此产生的模板将如下图所示。

同样地,你可以创建你的简单标签,并以你认为合适的方式使用它们。
包含性标签
这些标签通过渲染另一个模板来工作,当处理要在几个页面上找到的信息时,它们是必不可少的。
让我们创建一个简单的包含标签,计算用户的数量。
创建一个users.html 文件,该文件将由包含标签渲染。
在你的custom_tags.py 文件中,编辑并追加如下内容。
from django.contrib.auth.models import User
# Create show_users inclusion tag that will return all users and register it and indicate that it's going to render a users.html view.
@register.inclusion_tag('users.html')
def show_users():
obj = User.objects.values_list('username', flat=True)
return {'users': obj}
模板文件users.html ,看起来将如下图所示。
<ul>
{% for user in users %}
<li> {{ user }} </li>
{% endfor %}
</ul>
然后使contact.html ,看起来像这样。
<!-- Loading the custom_tags file to avail our tags and filters -->
{% load custom_tags %}
{% block content %}
<-- Using the my_contacts simple tag -->
<h3>You have {% my_contacts %} contacts</h3>
{% for contact in contacts %}
<div class="flex-box-container">
<!--Using the get_color and upper filters to change color and capitalize the contact name respectively-->
<div style="background-color: {{contact.name|get_color}};"><p >{{contact.name|upper}}</p></div>
<!-- Using the current_date simple tag -->
<div><b>Created:</b> {% current_date "%d/%m/%Y" %} </div>
</div>
{% endfor %}
<!--using the show_users inclusion tag -->
{% show_users %}
{% endblock content %}
现在产生的模板将如下图所示。

注意,通过添加show_users 标签,我们现在在联系人下面添加了一个用户。
总结
你现在已经成功创建了你的自定义模板标签和过滤器。你现在应该能够创建新的模板标签和过滤器,并在你的Django应用程序中需要的地方应用它们。