python后台架构Django教程:templates模板

2018-10-2609:09:53后端程序开发Comments2,538 views字数 6994阅读模式

每一个Web框架都需要一种很便利的方法用于动态生成HTML页面。 最常见的做法是使用模板。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

模版是纯文本文件,可以生成任何基于文本的文件格式,比如HTML,XML,CSV等。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

模板包含所需HTML页面的静态部分,以及一些特殊的模版语法,用于将动态内容插入静态部分。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

本节就来了解这些特殊的模版语法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

前面我们在views视图函数中学习了可以使用render函数、render_to_response等函数返回静态html模板视图、或将字典参数传递给模板视图,渲染动态html模板视图。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

一个简单的渲染模板示例如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

from django.shortcuts import render_to_response
from .models import User,Diary

# findalluser将数据库内存储的数据读出并展示出来。
def findalluser(request):
    allpeople = User.objects.all()  # 查询所有用户
    dict={
        'people_list':allpeople
    }
    return render_to_response("showuser.html",dict)  # 返回文件响应,第二个参数必须为字典

findalluser将数据库内存储的数据读出并结合html文件渲染出最后的响应hhtml源代码。这和jsp中的原理相同,python先将html文件的内容全部加载到内存中,再根据python的语法和传来的数据库数据生成html文件中python代码部分产生的文本,再将最终生成的html源代码返回到前端。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

配置引擎文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

模板引擎通过settings.py文件中的TEMPLATES设置来配置。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

搜索过程文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

当我们在views的视图函数中加载、搜索模板时,如下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

get_template('detail.html')

Django将按以下顺序查找story_detail.html:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

/home/html/example.com/detail.html('django'引擎)
/home/html/default/detail.html('django'引擎)
/home/html/jinja2/detail.html('jinja2'引擎)

当我们有多个app,并且在多个app下有相同模板名称时,例如
app1/templates/detail.html
app2/templates/detail.html文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

无论我们在哪个app的视图函数中搜索“detail.html”这个模板,都将只能搜索到第一个detail模板。所以我们要通过路径来区分模板。将文件目录构建成
app1/templates/app1/detail.html
app2/templates/app2/detail.html文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

这样我们在视图函数使用”app2/detail.html”的路径就能搜索不同app下的模板。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

基本语法 1、模板上下文文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

views视图函数传递给模板的只能是字典参数。这个字典参数被称为模板的上下文context。比如:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

render_to_response("showuser.html",{'key1':'value1','key2':object2})

在模板文件中可以直接通过键key来获取调用值value。比如下面的代码就表示字符串'value1'文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{{ key1}}

模板能够访问到的不仅仅是对象的属性(比如字段名称)和视图中传入的变量,还可以执行对象的方法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

比如QuerySets提供了count()方法来计算含有对象的总数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{{ users.count }}

你可以像这样获取所有关于当前用户集合的数目文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

2、变量文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

变量看起来就像是这样: {{ variable }}。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

当模版引擎遇到一个变量,它将从上下文context中获取这个变量的值,然后用值替换掉它本身。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

当模版系统遇到点(“.”),它将以这样的顺序查询这个圆点具体代表的功能:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

字典查询(Dictionary lookup) 属性或方法查询(Attribute or method lookup) 数字索引查询(Numeric index lookup)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

如果你使用的变量不存在,模版系统将插入string_if_invalid选项的值,默认设置为”(空字符串)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

注意:像{{ foo.bar }}这种模版表达式中的“bar”,如果在模版上下文中存在,将解释为一个字面意义的字符串而不是使用变量bar的值 。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

3、过滤器文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

过滤器的形式:
过滤器看起来是这样的:{{ name|lower }}。使用管道符号(|)来应用过滤器。该过滤器将文本转换成小写。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

多级过滤器:
{{ text|escape|linebreaks }}就是一个常用的过滤器链,它首先转移文本内容,然后把文本行转成文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

标签。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

过滤器带参:
{{ list|join:”, ” }}。使用逗号和空格去连接一个列表中的元素文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

过滤器的作用是对变量进行预处理,相当于函数的功能,过滤器的工作都可以在views视图函数中完成。也可以通过自定义函数来实现自定义过滤器。在后面的自定义过滤器中我们会了解。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

例1、default文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

为false或者空变量提供默认值,像这样:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{{ value|default:"nothing" }}

例2、length文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

返回值的长度。它对字符串和列表都起作用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{{ value|length }}

如果value是[‘a’, ‘b’, ‘c’, ‘d’],那么输出4。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

为模版过滤器提供参数的方式是:过滤器后加个冒号,再紧跟参数,中间不能有空格!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

目前只能为过滤器最多提供一个参数!文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

过滤器 说明 add 加法 addslashes 添加斜杠 capfirst 首字母大写 center 文本居中 cut 切除字符 date 日期格式化 default 设置默认值 default_if_none 为None设置默认值 dictsort 字典排序 dictsortreversed 字典反向排序 pisibleby 整除判断 escape 转义 escapejs 转义js代码 filesizeformat 文件尺寸人性化显示 first 第一个元素 floatformat 浮点数格式化 force_escape 强制立刻转义 get_digit 获取数字 iriencode 转换IRI join 字符列表链接 last 最后一个 length 长度 length_is 长度等于 linebreaks 行转换 linebreaksbr 行转换 linenumbers 行号 ljust 左对齐 lower 小写 make_list 分割成字符列表 phone2numeric 电话号码 pluralize 复数形式 pprint 调试 random 随机获取 rjust 右对齐 safe 安全确认 safeseq 列表安全确认 slice 切片 slugify 转换成ASCII stringformat 字符串格式化 striptags 去除HTML中的标签 time 时间格式化 timesince 从何时开始 timeuntil 到何时多久 title 所有单词首字母大写 truncatechars 截断字符 truncatechars_html 截断字符 truncatewords 截断单词 truncatewords_html 截断单词 unordered_list 无序列表 upper 大写 urlencode 转义url urlize url转成可点击的链接 urlizetrunc urlize的截断方式 wordcount 单词计数 wordwrap 单词包裹 yesno 将True,False和None,映射成字符串‘yes’,‘no’,‘maybe’ 4、标签文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

标签看起来像是这样的: {% tag %}。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

标签比变量复杂得多,有些用于在输出中创建文本,有些用于控制循环或判断逻辑,有些用于加载外部信息到模板中供以后的变量使用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

一些标签需要开始和结束标签(即 {% 标签 %} … 标签 内容 … {% ENDTAG %})。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

Django自带了大约24个内置的模版标签。下面是一些常用的标签文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

1. for循环标签文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% for user in people_list %} {{ user.username }} {% endfor %}文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

for循环中可以通过forloop.counter来获取你当前循环的次数。forloop.counter是DJango模板系统专门提供的一个变量,一般用来给循环项目添加有序数标。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

2. if,elif和else标签文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% if athlete_list %}
    Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
    Athletes should be out of the locker room soon!
{% else %}
    No athletes.
{% endif %}

需要注意,大多数模版过滤器都返回字符串类型,所以在if标签中使用过滤器做整数类型的比较通常是错误的,但length是一个例外。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

3. autoescape文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

控制自动转义是否可用。参数是on或off。 该标签会以一个endautoescape作为结束标签.文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% autoescape on %}
    {{ body }}
{% endautoescape %}

4. block文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

block标签可以被子模板覆盖。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

5. comment文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

在{% comment %}和{% endcomment %}之间的内容会被忽略,作为注释。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

比如,当要注释掉一些代码时,可以用此来记录代码被注释掉的原因。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

例如:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

Rendered text with {{ pub_date|date:"c" }}文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% comment "Optional note" %}文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

Commented out text with {{ create_date|date:"c" }}文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% endcomment %}文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

6. csrf_token文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

这个标签用于跨站请求伪造保护。常用于为form表单提供csrf令牌。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

7. cycle文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

每当这个标签被访问,返回它的下一个元素。第一次访问返回第一个元素,第二次访问返回第二个参数,以此类推. 一旦所有的变量都被访问过了,就会回到最开始的地方,重复下去。这个标签在循环中特别有用:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% for o in some_list %}
    
        ...
    
{% endfor %}

第一次迭代产生的HTML引用了row1类,第二次则是row2类,第三次又是row1 类,如此类推。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

也可以使用变量, 例如,如果你有两个模版变量:rowvalue1和rowvalue2, 可以让他们的值像这样替换:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% for o in some_list %}
    
        ...
    
{% endfor %}

在某些情况下,可能需要连续引用一个当前循环的值,而不前进到下一个循环值。要达到这个目的,只需使用as来给{% cycle %}取一个别名,就像这样:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

    ...
    ...


    ...
    ...

将输出:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

    ...
    ...


    ...
    ...

8. debug文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

输出整个调试信息,包括当前上下文和导入的模块。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

9. filter文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

通过一个或多个过滤器对内容过滤。需要结束标签endfilter。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

例如:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% filter force_escape|lower %}
    This text will be HTML-escaped, and will appear in all lowercase.
{% endfilter %}

10. include文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

加载指定的模板并以标签内的参数渲染。这是一种引入别的模板的方法,一定要将include和extend区分开!include类似Python的import。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% include "http://blog.csdn.net/luanpeng825485697/article/details/foo/bar.html" %}

也可以使用变量名template_name:
{% include template_name %}

11. spaceless文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

删除HTML标签之间的空白,包括制表符和换行。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% spaceless %}

Foo文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% endspaceless %} 五、注释文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

要注释模版中一行的部分内容,使用注释语法:{# #}。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{# {% if foo %}bar{% else %} #}

以上是单行注释(在{# …. #}中,不允许有新行)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

如果需要注释掉模版中的多行内容,请使用comment标签。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

七、自动转义HTML文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

默认情况下,Django中的每个模板会自动转义每个变量。依次来避免跨站脚本攻击(Cross Site Scripting)(XSS)。也就是说,下面五个字符将被转义:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

<会转换为< >会转换为> '(单引号)转换为' "(双引号)会转换为" &会转换为&文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

但是,有时,模板变量含有一些你打算渲染成原始HTML的数据,你并不想转义这些内容。 例如,你可能会在数据库中储存一些HTML代码,并且直接在模板中嵌入它们。或者,你可能使用Django的模板系统来生成不是HTML的文本 – 比如邮件信息。要怎么办呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

对于单个变量:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

使用safe过滤器来关闭变量上的自动转义:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}

对于模板块:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

要控制模板上的自动转义,将模板(或者模板中的特定区域)包裹在autoescape标签中,autoescape标签接受on或者off作为它的参数。像这样:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% autoescape off %}
    This will not be auto-escaped: {{ data }}.

    Nor this: {{ other_data }}
    {% autoescape on %}
        Auto-escaping applies again: {{ name }}
    {% endautoescape %}
{% endautoescape %}

过滤器的字符串参数不自动转义文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

过滤器的参数可以是字符串,所有这种字符串参数在插入模板时都不会进行任何自动转义,所以需要程序员自己转义。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{{ data|default:"3 < 2" }}  {# 正确的做法#}
{{ data|default:"3 < 2" }}     {# 错误的做法#}

使用自定义标签和过滤器文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

一、前置步骤文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

第一步,在app中新建一个templatetags包(名字固定,不能变,只能是这个),和views.py、models.py等文件处于同一级别目录下。这是一个包!不要忘记创建__init__.py文件以使得该目录可以作为Python的包。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

在添加templatetags包后,需要重新启动服务器,然后才能在模板中使用标签或过滤器。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

将你自定义的标签和过滤器将放在templatetags包下的一个模块里。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

这个模块的名字是后面载入标签时使用的标签名,所以要谨慎的选择名字以防与其他应用下的自定义标签和过滤器名字冲突,当然更不能与Django内置的冲突。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

假设你自定义的标签/过滤器在一个名为poll_extras.py的文件中,那么你的app目录结构看起来应该是这样的:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

app1/
    __init__.py
    models.py
    templatetags/
        __init__.py
        poll_extras.py
    views.py

为了让{% load xxx %}标签正常工作,包含自定义标签的app必须在INSTALLED_APPS中注册。然后你就可以在模板中像如下这样使用:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{% load poll_extras %}

在templatetags包中放多少个模块没有限制。只需要记住{% load xxx %}将会载入给定模块名中的标签/过滤器,而不是app中所有的标签和过滤器。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

要在模块内自定义标签,首先,这个模块必须包含一个名为register的变量,它是template.Library的一个实例,所有的标签和过滤器都是在其中注册的。 所以把如下的内容放在你的模块的顶部:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

from django import template

register = template.Library()

二、自定义模板过滤器文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

1、 编写过滤器文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

自定义过滤器就是一个带有一个或两个参数的Python函数:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

注意:这个Python函数的第一个参数是你要过滤的对象,是必须要有的,第二个参数才是你自定义的参数。而且最多总共只能有两个参数,所以你只能自定义一个参数!这是过滤器的先天限制。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

变量的值:不一定是字符串形式。 参数的值:可以有一个初始值,或者完全不要这个参数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

例如,在{{ var|foo:”bar” }}中,foo过滤器应当传入变量var和参数”bar”。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

由于模板语言没有提供异常处理,任何从过滤器中抛出的异常都将会显示为服务器错误。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

下面是一个定义过滤器的例子:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

def cut(value, arg):
    """将value中的所有arg部分切除掉"""
    return value.replace(arg, '')

下面是这个过滤器的使用方法:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

{{ somevariable|cut:"0" }}

2、注册过滤器文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

一旦你写好了过滤器函数,就需要注册它,方法是调用register.filter,比如:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

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

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

三、自定义模板标签文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

标签比过滤器更复杂,因为标签可以做任何事情。Django提供了大量的快捷方式,使得编写标签比较容易。 对于我们一般的自定义标签来说,simple_tag是最重要的,它帮助你将一个Python函数注册为一个简单的模版标签。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/7259.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/bc/7259.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定