Django模板语言

知识点:

  1. 代码布局
  2. 编写自定义模板过滤器
  3. 简单标签
  4. 包含标签
  5. 分配标签
  6. 静态文件加载

为了解决应用中展示逻辑的需求,Django的模板语言提供了各式各样的built-in tags and filters。 然而,你或许会发现模板内建的这些工具集合不一定能全部满足你的功能需要。 您可以通过使用Python定义自定义标签和过滤器来扩展模板引擎,然后使用{% load %}标签。

代码布局

指定自定义模板标签和过滤器的最常见的地方在Django应用程序中。

当将Django应用程序添加到INSTALLED_APPS中时,在下面描述的常规位置中定义的任何标签将自动在模板中加载。

这个应用应该包含一个templatetags 目录,和views.py、models.py等文件处于同一级别目录下。 如果目录不存在则创建它——不要忘记创建init.py 文件以使得该目录可以作为Python 的包。

你的自定义的标签和过滤器将放在templatetags 目录下的一个模块里。 这个模块的名字是你稍后将要载入标签时使用的,所以要谨慎的选择名字以防与其他应用下的自定义标签和过滤器名字冲突。

例如,你的自定义标签/过滤器在一个名为common_extras.py的文件中,那么你的app目录结构看起来应该是这样的:

common/
    __init__.py
    models.py
    templatetags/
        __init__.py
        common_extras.py
    views.py

在模板中像如下这样使用:

{% load common_extras %}

为了让{% load %}标签工作,包含自定义标签的应用必须在INSTALLED_APPS中。在 templatetags 包中放多少个模块没有限制。 只需要记住{% load %} 声明将会载入给定模块名中的标签/过滤器,而不是应用的名称。

为了成为一个可用的标签库,这个模块必须包含一个名为 register的变量,它是template.Library 的一个实例,所有的标签和过滤器都是在其中注册的。 所以把如下的内容放在你的模块的顶部:

from django import template

register = template.Library()

编写自定义模板过滤器

自定义过滤器就是一个带有一个或两个参数的Python 函数:

  • (输入的)变量的值 —— 不一定是字符串形式。
  • 参数的值 —— 可以有一个初始值,或者完全不要这个参数。

例如,在{{ var|foo:"bar" }}中,foo过滤器应当传入变量var和参数 "bar"。

定义过滤器的例子:

def mycut(value, arg):
    return value.replace(arg, '')

这个过滤器的使用:

{{ somevariable|mycut:"0" }}

大多数过滤器没有参数。 在这种情况下,你的函数不带这个参数即可。 例如:

def mylower(value):
    return value.lower()

注册自定义过滤器

django.template.Library.filter()

让自定义的过滤器在Django模板语言中可用,就需要把它注册为你的 Library实例:

register.filter('mycut', mycut)
register.filter('mylower', mylower)

Library.filter()方法需要两个参数:

  1. 过滤器的名称(一个字符串对象)
  2. 编译的函数 – 一个Python函数(不要把函数名写成字符串)

还可以把register.filter()用作装饰器:

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

@register.filter
def mylower(value):
    return value.lower()

没有声明 name 参数,Django将使用函数名作为过滤器的名字。

如果你正在编写一个只希望用一个字符串来作为第一个参数的模板过滤器,你应当使用stringfilter装饰器。 这将在对象被传入你的函数之前把这个对象转换成它的字符串值:

from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
@register.filter
@stringfilter    #注释掉此句传递int类型会报错
def mylower(value):
    return value.lower()

编写自定义模板标签

简单标签django.template.Library.simple_tag()

许多模板标签需要许多参数 - 字符串或模板变量,并且仅在基于输入参数和一些外部信息进行一些处理后返回结果。 例如,current_time 标签可能接受一个格式字符串,并返回与之对应的格式化后的时间。

为了简单化这些类型标签的创建,Django 提供一个辅助函数simple_tag。 这个函数是django.template.Library 的一个方法,接受一个任意数目的参数的函数,将其包装在一个render 函数和上面提到的其他必要部分中,并在模板系统中注册它。

注册标签,向模块的Library实例注册代码

register.tag('current_time', do_current_time)

tag()方法有两个参数:

  1. 模板标记的名称 - 字符串。 如果省略,将使用编译函数的名称。
  2. 编译的函数 – 一个Python函数(不要把函数名写成字符串)

与过滤器注册一样,也可以将其用作装饰器。

例子:

# hello_django/music/templatetages/common_tag.py

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 参数︰

# hello_django/music/templatetages/common_tag.py

@register.simple_tag(takes_context=True)
def current_time(context ):
    tm = context['format_string']
    return datetime.datetime.now().strftime(tm)
    
# 这里的tm是从视图函数context中传进来的。

包含标签django.template.Library.inclusion_tag()

另一种常见类型的模板标签是通过渲染另外一个模板来显示一些数据。这些类型的标签被称为"Inclusion 标签"。

例子:

# hello_django/music/templatetages/common_tag.py

@register.inclusion_tag('music/show_tag.html')
def show_results():
    li = ['python','java','c++']
    return {'choices':li}

{# hello_django/music/templates/show_tag.html#}

<ul>
    {% for i in choices %}
        <li>{{ i }}</li>
    {% endfor %}
</ul>

分配标签

为了简单化设置上下文中变量的标签的创建,Django 提供一个辅助函数assignment_tag。 除了将标签的结果存储在指定的上下文变量中,而不是直接输出,该函数的工作方式与simple_tag()相同。

我们之前的current_time 函数从而可以这样写︰

# hello_django/music/templatetages/common_tag

@register.assignment_tag
def current_time_1(format_string):
    return datetime.datetime.now().strftime(format_string)

然后你可以使用as 参数后面跟随变量的名称将结果存储在模板变量中,并将它输出到你觉得合适的地方︰

{% current_time_1 '%Y-%m-%d %H:%M:%P' as ctime %}
The time is {{ ctime }}

模板加载静态文件

1、在settings中,找到INSTALLED_APPS,然后确保有django.contrib.staticfiles。

2、在settings中,选择性的设置STATIC_ROOT和STATIC_URL以及STATICFILES_DIRS

3、STATICFILES_DIRS可以设置绝对路径也可以是相对路径。同templates

4、默认STATICFILES_FINDERS会到安装了的app下面的static文件夹找静态文件。

5、在模板中,使用static标签加载静态文件。注意路径!

例子:

我们在app下面创建一个static的目录,在目录中添加三种静态文件:

# hello_djagngo/music/static/myjs.js
alert('hahahaha');

# --------------------------------

# hello_djagngo/music/static/mystyle.css
body{
    background: skyblue;
}
#---------------------------------

# hello_djagngo/music/static/myimage.jpg
##存入图片

静态文件创建好了之后就可以在模板里面加载静态文件。

{# hello_django/music/templates/index.html#}

    <link rel="stylesheet" href="{% static 'mystyle.css' %}">
    <script src="{% static 'myjs.js' %}"></script>
    图片:
    <img src="{% static 'myimage.jpg' %}" alt=""/>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容