3 - django-template模板基本使用
1 Template
使用 Django的 模板系统 (Template System)来实现将Python代码和HTML代码分开的目的。
python的模板包涵:HTML代码+逻辑控制代码 , 将具体数据嵌入到前端模板的语法,在一个html文件中包含模板语法的文件,可以认为是模板文件
1.1 模板的基础使用
主要分为两部分:渲染变量使用双大括号{{ }},渲染标签则使用双大括号双百分号{% %}
1.1.1 变量
在html页面中使用两个大括号包起来的字符串叫做变量:
{{ Var_name }}
这里通过python django的shell环境来举例(在这个环境中可以直接引用 所属django模块中的变量等信息)
# 使用 manage.py进入shell界面
终端中输入:python manage.py shell
>>> from django.template import Context,Template
>>> t = Template('My name is {{ name }}')
>>> c = Context({'name':'dachenzi'})
>>> t.render(c) # render会把变量进行渲染
'My name is dachenzi'
>>>
1.1.2 注释标签
单行注释 {# #}。
多行注释 {% comment %} ... {% endcomment %}.
{# 这是一个注释 #}
{% comment %}
这是多行注释
{% endcomment %}.
1.1.3 深度查询
如果传递的变量是属组或者字典,那么需要进行深度查询(通过使用.(点)来完成深度查询):
{{ Var_Name.username }} # 获取Var_Name中的key为:username的值 --> 变量为字典类型
{{ Var_Name.2 }} # 获取Var_Name中第2个值 --> 变量为list类型
使用.带进行深度查询,查询list类型的数据
>>> from django.template import context,Template
>>> t = Template('hello {{ name.1}}')
>>> c = Context({'name':[1,2,3]})
>>> t.render(c)
'hello 2'
使用items循环字典类型(不加括号)
{% for key,value in user_dict.items %}
<li>{{ key }}-{{ value }}</li>
{% endfor %}
1.1.4 内置变量过滤器filter
可以理解为python中的内置函数,过滤器是模板的特有语法,通过前端来过滤部分数据。注意filter只能传递一个参数(也可以说是两个参数,因为第一个个参数已经固定,就是被处理的那个)。
格式:
{{ var|method:parameter}}
method表示过滤器部分过滤器如下:
| 过滤器 | 说明 | 举例 |
|---|---|---|
| first | 取列表第一个元素 | |
| last | 取列表最后元素 | |
| capfirst | 首字母大写 | |
| cut | 从字符串中移除指定的字符 | {{ 'aLbLcL'|cut:'L' }}答案是abc |
| yesno | 变量可以是True、False、None,yesno的参数 给定逗号分隔的三个值,返回3个值中的一个。 True对应第一个 False对应第二个 None对应第三个 如果参数只有2个,None等效False处理 |
{{ value | yesno:"yeah,no,maybe"}} |
| add | 加法。参数是负数就是减法 | 数字加{{ value | add:"100"}} 列表合并{{mylist | add:newlist}} |
| divisibleby | 能否被整除 {{ value | divisibleby:"3" }}能被3整除返回True | |
| addslashes | 在反斜杠、单引号或者双引号前面加上反斜杠 {{ value | addslashes }} | |
| length | 返回变量的长度 | {% if my_list | length > 1 %} |
| default | 变量等价False则使用缺省值 | {{ value | default:"nothing" }} |
| default_if_none | 变量为None使用缺省值 | {{ value |default_if_none:"nothing" }} |
| date | 格式化 date 或者 datetime 对象 | 实例:{{my_dict.date|date:'Y n j'}} Y 2000 年 n 1~12 月 j 1~31 日 |
| 切片相关 | {{ value7|filesizeformat }}文件的字节数 {{ value7|first }}第一个字符 {{ value7|length }}长度 {{ value7|slice:":-1" }}切片 |
1.1.5 自定义过滤器之filter
内置的过滤器总有不能满足我们业务需求的时候,这时,我们可以自定义过滤器,官方文档:https://docs.djangoproject.com/zh-hans/2.0/howto/custom-template-tags/
具体步骤为:
- 在
app目录下创建templatetags包(名称必须为templatetags) - 在包下创建任意 .py 文件,如:my_tags.py ,用来存放自定义的filter或tag函数
- 编写自定义过滤器
- 在模板中加载templatetags并调用
下面是my_tags.py的文件内容
from django import template # 需要先导入文件
register = template.Library() # register的名字是固定的,不可改变,因为下面会进行调用
@register.filter # 注册
def multi(num1,num2):
return num1 * num2
在引用的html模板文件中进行加载(可以放在模板文件头部,或者用之前加载也可以,当和extend同时使用时,放在entend下面)
{% load my_tags %} # 这里的名字就是我们创建的my_tags.py的文件名
调用
{{ hello|multi:2 }} # hello 表示传递的第一个参数,2表示传递的是第二个参数,冒号后面必须要紧跟传递的参数,多一个空格都不行
PS:filter 的函数只能接受一个额外参数(两个参数,默认会把要处理的对象当作第一个参数,第二个参数是我们需要传递的参数),可以用于if/for等语句的条件,渲染时 使用 {{ 参数1 | xxx:参数2 }} 渲染 。
1.1.6 自定义过滤器之simple_tag
simpletag与filter不同的是,可以接受多个参数,但不可以用if/for等语句的条件,使用 {% xxx %} 渲染,创建步骤与filter相同
编写simpletag
# my_tags.py文件
from django import template # 需要先导入文件
register = template.Library() # register的名字是固定的,不可改变,因为下面会进行调用
@register.simple_tag # 必须要装饰我们自定义的函数才行
def simple_tag_multi(num1,num2):
return num1 * num2
加载完毕后调用方式使用 {% %}
{% simple_tag_multi 10 20 %} # 参数以空格隔开,多个空格效果相同
1.2 逻辑控制语法
循环等逻辑语句需要使用{% %} 来进行渲染
1.2.1 for标签
{% for i in li %} # li 为后端传递给模板的变量
<p>{{ i }}</p>
{% endfor %} #使用endfor来表示循环结束
在for循环中存在一个forloop变量,该变量记录循环相关数据
- forloop.counter:表示当前迭代数(第几次循环)从1开始
- forloop.counter0:同上,但是从0开始
- forloop.first:判断此次循环是否是第一次循环,是则返回True
- forloop.revcounter:表示当前迭代数(第几次循环)- 倒序
- forloop.last:判断此次循环是否是最后一次循环
- forloop.parentloop:用于在嵌套循环时,获取父循环的上面的信息
reversed和empty:
reversed:对可迭代对象进行逆序empty:如果可迭代对象为空
{% for athlete in athlete_list reversed %}
...
{% empty %}
... 如果被迭代的列表是空的或者不存在,执行empty
{% endfor %}
1.2.2 if标签
{% if li.1 > 100 %}
<p> 大于 </p>
{% elif li.1 < 100 %}
<p> 小于 </p>
{% else %}
<p> 等于 </p>
{% endif %} #使用endif来表示条件判断结束
1.2.3 ifequal/ifnotequal 标签
{% ifequal %} 标签比较两个值,当他们相等时,显示在 {% ifequal %} 和 {% endifequal %} 之中所有的值。
下面的例子比较两个模板变量 user 和 currentuser :
{% ifequal user currentuser %}
<h1>Welcome!</h1>
{% endifequal %}
和 {% if %} 类似, {% ifequal %} 支持可选的 {% else%} 标签
{% ifequal section 'sitenews' %}
<h1>Site News</h1>
{% else %}
<h1>No News Here</h1>
{% endifequal %}
1.3 特殊标签
{% url 'varname' %}:引用路由配置的地址
<form action="{% url "LOGIN"%}" method="POST"> # 路由引用
<input type="text">
<input type="submit" value="提交">
</form>
{% verbatim %}:禁止render解析。
既在有的时候我们仅仅只是想打印出 {{ hello }} 而已,使用verbatim来禁止render进行解析
{% verbatim %}
{{ hello }}
{% endverbatim %}
# 使用verbatim 包起来的代码 将不会进行解析
{% csrf_token %}:用于跨站请求伪造保护,防止跨站攻击的。
<form>
{% csrf_token %}
</form>
一般用在form表单中。
1.4 extends模板继承
到目前为止,我们的模板范例都只是些零星的 HTML 片段,但在实际应用中,你将用 Django 模板系统来创建整个 HTML 页面。 这就带来一个常见的 Web 开发问题: 在整个网站中,如何减少共用页面区域(比如站点导航)所引起的重复和冗余代码?Django 解决此类问题的首选方法是使用一种优雅的策略 —— 模板继承.
本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载.
编写模板需要使用模板标签:
{% block name%} {% endblock %}:所有的 {% block %} 标签告诉模板引擎,子模板可以重载这些部分。 每个{% block %}标签所要做的是告诉模板引擎,该模板下的这一块内容将有可能被子模板覆盖。
下面是一个html模板文件:
// index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="title"></div>
<div class="left">
<div class="left_list">
<a href="/booklist/">文章列表</a>
</div>
</div>
<div class="right">
{% block content %} // 这里定义content,表示这里可以被继承模板进行替换
{% endblock %} // 包起来的表示代码段
</div>
</body>
</html>
HTML中包含 block 语句块的都可以称为模板文件
子模板进行继承,并定制自己要显示的内容(子模板不需要额外的html代码,其代码都来自于模板文件),仅仅需要定义 block块内的信息即可,当然也可以不定义,或者在block块中调用父模板的内容。
// test.html
{% extends 'index.html' %} // 继承模板文件
{% block content %} // 针对模板中content的代码块进行定义
<h1>hello world</h1>
<h1>hello world</h1>
<h1>hello world</h1>
<h1>hello world</h1>
<h1>hello world</h1>
<h1>hello world</h1>
{% endblock %}
使用注意:
- 如果在模板中使用 {% extends %} ,必须保证其为模板中的
第一个模板标记(html首部)。 否则,模板继承将不起作用。 - 一般来说,基础模板中的 {% block %} 标签越多越好。 记住,子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越多越好。
- 如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 {% block %} 中。如果你需要访问父模板中的块的内容,使用
{{ block.super }}这个标签吧,这一个魔法变量将会表现出父模板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。 - 不允许在同一个模板中定义多个同名的 {% block %} .存在这样的限制是因为block 标签的工作方式是双向的。也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。
一个html文件只能引入一个模版
1.5 include引入
在很多网站中,基本上的都会有一个开头和一个结尾,在每一个网页中都会显示。相对于这种的来说,在Django中,最好的方法就是使用include的标签,在每一个模板中都加入这个开头和结尾的标签。
简单来说,就是那些多个页面都需要的公共标签放在一个统一的html文件,供其他html文件引入。
{% include 'tpl.html' %} : 表示引入tpl.html文件。
看下面的例子:
# -------------------- tpl.html --------------------
<div>
<h1>hello world</h1>
</div>
# -------------------- xxx.html --------------------
...
<div>
{% include 'tpl.html' %}
{% include 'tpl.html' %} // tpl.html的全部内容会在这里填充
...
</div>
...
在一个页面中可以通过include引入不同的公共组件。
3 - django-template模板基本使用的更多相关文章
- Django Template模板
Django Template 你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python 代码之中. 下面我们来调用html views def ind ...
- django template 模板
九.Template模板 Template 模板是根据view传过来数据在html展示的功能,典型python 模板jinjia2库提供丰富的上下文展示func 创建template位置在项目下与ap ...
- django template模板 母板 include导入
一,使用{% block name %}{% endblock %}定义一个模板,在模板页面中它的内容为空,在各页面用{% block name %}自己的标签内容{% endblock %}调用. ...
- Django基础,Day10 - template 模板引擎与路径设置
作为一个Web框架,Django需要一个方便的方式来生成动态的HTML.最常见的方法依赖于模板.模板包含所需的HTML输出的静态部分以及一些特殊的语法描述如何插入动态内容. Django框架后端默认支 ...
- Django Template(模板)
一.模板组成 组成:HTML代码 + 逻辑控制代码 二.逻辑控制代码的组成 1.变量 语法格式 : {{ name }} # 使用双大括号来引用变量 1.Template和Context对象(不推荐使 ...
- Django:模板template(一)
把模板的过程.语法.标签.反向地址解析.过滤器.模板继承与HTML转义记下笔记 1.概述及demo 动态生成HTML 模板的设计实现业务逻辑(View)和显示内容(template)的分离 一个模板可 ...
- Django之模板Template
模板介绍 作为Web框架,Django提供了模板,可以很便利的动态生成HTML 模版系统致力于表达外观,而不是程序逻辑 模板的设计实现了业务逻辑(view)与显示内容(template)的分离,一个视 ...
- Django之模板配置(template)
Django模板系统 官方文档 jinja2模块中文 jinja2模块官方 常用语法 只需要记两种特殊符号: {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 在Djan ...
- Django基础——模板层(template) (Day67)
阅读目录 变量 标签 自定义过滤器和标签 模板层(template) 你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. 1 2 3 4 ...
- django基础2: 路由配置系统,URLconf的正则字符串参数,命名空间模式,View(视图),Request对象,Response对象,JsonResponse对象,Template模板系统
Django基础二 request request这个参数1. 封装了所有跟请求相关的数据,是一个对象 2. 目前我们学过1. request.method GET,POST ...2. reques ...
随机推荐
- zabbix短信(阿里云短信平台)与邮件报警
环境说明 操作系统 centos7 zabbix_server zabbix 4.0.3 python 3.6.5 短信平台 阿里云短信 zabbix_server配置信息 1 [root@cp-hb ...
- Codeforces Round #526 Div. 1 自闭记
日常猝死. A:f[i]表示子树内包含根且可以继续向上延伸的路径的最大价值,统计答案考虑合并两条路径即可. #include<iostream> #include<cstdio> ...
- YAPTCHA UVALive - 4382(换元+威尔逊定理)
题意就是叫你求上述那个公式在不同N下的结果. 思路:很显然的将上述式子换下元另p=3k+7则有 Σ[(p-1)!+1/p-[(p-1)!/p]] 接下来用到一个威尔逊定理,如果p为素数则 ( p -1 ...
- Ubuntu实用软件安装[转]
Gedit编辑器配置 Ubuntu14.04从安装软件到卸载软件,删除安装包 linux wget 命令用法详解(附实例说明) ==================================== ...
- [AT2567] [arc074_c] RGB Sequence
题目链接 AtCoder:https://arc074.contest.atcoder.jp/tasks/arc074_c 洛谷:https://www.luogu.org/problemnew/sh ...
- [UVALive 3902] Network
图片加载可能有点慢,请跳过题面先看题解,谢谢 一道简单的贪心题,而且根节点已经给你了(\(S\)),这就很好做了. 显然,深度小于等于 \(k\) 的都不用管了(\(S\) 深度为0),那么我们只需要 ...
- 【agc006f】Blackout(神仙题)
[agc006f]Blackout(神仙题) 翻译 给定一个\(n*n\)的网格图,有些格子是黑色的.如果\((x,y),(y,z)\)都是黑色的,那么\((y,x)\)也会被染黑,求最终黑格子数量. ...
- 洛谷 P1783 海滩防御 解题报告
P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...
- 音视频处理之FFmpeg+SDL+MFC视频播放器20180411
一.FFmpeg+SDL+MFC视频播放器 1.MFC知识 1).创建MFC工程的方法 打开VC++ 文件->新建->项目->MFC应用程序 应用程序类型->基于对话框 取消勾 ...
- jq获取兄弟节点
$('#id').siblings() 当前元素所有的兄弟节点$('#id').prev() 当前元素前一个兄弟节点$('#id').prevaAll() 当前元素之前所有的兄弟节点$('#id'). ...