Django第十篇-----关于模板的高级话题---下半篇

目录

自定义模板标签和过滤器

自定义模板过滤器

过滤器的定义:

注册自定义的过滤器

自定义模板标签

引入标签


自定义模板标签和过滤器

Django 的模板语言自带了丰富的标签和过滤器,能满足常见的表现逻辑需求。但是,这些内建的标签和过滤器可能缺少你需要的功能。
我们可以扩展模板引擎,使用 Python 自定义标签和过滤器,然后使用 {% load %} 标签加载,让自定义的标签和过滤器可在模板中使用。

自定义模板过滤器

自定义的过滤器其实就是普通的 Python 函数,接受一个或多个参数:

1. 变量的值(输入),不一定是字符串。
2. 参数的值,可以有默认值,也可以留空。

例如,对 {{ var|foo:"bar" }} 来说,传给 foo 过滤器的变量是 var ,参数是 "bar" 。因为模板语言没有提供异常处理功能,所以模板过滤器抛出的异常会以服务器错误体现出来。

过滤器的定义:

def cut(value, arg):
    """Removes all values of arg from the given string"""
    return value.replace(arg, '')

这个过滤器的用法举例如下:

{{ somevariable|cut:"0" }}

多数过滤器没有参数。此时,在函数中留空参数即可。例如:

def lower(value): # 只有一个参数
    """Converts a string into all lowercase"""
    return value.lower()

注册自定义的过滤器

定义好过滤器之后,要使用 Library 实例注册,让 Django 的模板语言知道它的存在:

register.filter('cut', cut)
register.filter('lower', lower)

Library.filter() 有两个参数:

1. 过滤器的名称,一个字符串。
2. 负责处理过滤器的函数,一个 Python 函数(不是函数名称的字符串形式)。

register.filter() 也可以作为装饰器使用:

@register.filter(name='cut')
def cut(value, arg):
    return value.replace(arg, '')
@register.filter
def lower(value):
    return value.lower()

自定义模板标签

标签能做任何事情,比过滤器复杂。Django 提供了一些快捷方式,简化了多数标签类型的编写。首先,我们将探讨这些快捷方式,然后说明在快捷方式不够用时如何从头开始编写标签。

例如有个 current_time 标签,它接受一个格式字符串,返回格式化后的时间字符串

据此, current_time 函数可以这么编写:

import datetime
from django import template
register = template.Library()
@register.simple_tag
def current_time(format_string):
    return datetime.datetime.now().strftime(format_string)

如果模板标签需要访问当前上下文,注册标签时指定 takes_context 参数:

@register.simple_tag(takes_context=True)
def current_time(context, format_string):
    timezone = context['timezone']
    return your_get_current_time_method(timezone, format_string)

如果想为标签起个别的名称,指定 name 参数:

register.simple_tag(lambda x: x - 1, name='minusone')
@register.simple_tag(name='minustwo')
def some_function(value):
    return value - 2

使用 simple_tag 装饰的函数可以接受任意个位置参数和关键字参数。例如:

@register.simple_tag
def my_tag(a, b, *args, **kwargs):
    warning = kwargs['warning']
    profile = kwargs['profile']
    ...
    return ...

然后在模板中可以把任意个参数(以空格分开)传给这个标签。与 Python 代码一样,关键字参数的值使用等号( = )设定,而且必须放在位置参数后面。例如:

{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}

引入标签

首先,要定义一个接受参数的函数,生成一个字典,为结果提供数据。注意,我们只需返回一个字典,而不是其他复杂的数据结构。返回的字典在模板片段的上下文中使用。

def books_for_author(author):
    books = Book.objects.filter(authors__id=author.id)
    return {'books': books}

Author 对象名下的图书列表。我们将像这样使用这个标签:

{% books_for_author author %}

得到的结果如下:

<ul>
    <li>The Cat In The Hat</li>
    <li>Hop On Pop</li>
    <li>Green Eggs And Ham</li>
</ul>

然后,创建用于渲染标签输出的模板。对这个标签来说,模板十分简单:

<ul>
{% for book in books %}
    <li>{{ book.title }}</li>
{% endfor %}
</ul

猜你喜欢

转载自blog.csdn.net/Da___Vinci/article/details/84578741