模板介绍
作为web框架,Django提供了模板,用于编写html代码(嵌入模板代码,更快更方便的完成页面开发,在通过视图中渲染模板,将最终生成的页面返回给浏览器(客户端))。模板是关于外表的渲染的,程序逻辑反而不是很重,模板的设计实现了业务逻辑View与显示的内容Template的解耦。一个视图可以使用任意的模板,一个模板可以被多个视图使用。
模板包含两部分:
静态部分:html、css、js
动态部分:模板语言
项目准备:
新建项目---------创建应用------安装应用(设置里面)--------配置模板路径---------本地化---------mysql数据库(导包)---------URLconf--------视图
mysql使用之前的数据库
模板处理:
Django处理模板两个阶段:
1、加载:根据路径找到模板,编译放在内存中
2、渲染:使用上下文数据对模板传值,并返回动态生成的网页(render函数,渲染:减少开发人员重复写,加载渲染代码)
模板配置:(在设置中添加模板路径)(TEMPLATES中配置):
'DIRS': [os.path.join(BASE_DIR, 'templates')],
创建模板文件:
在视图函数中,加载渲染模板。
模板语言
作用:
获取、处理传入到模板中的上下文数据,动态的产生页面内容。
包括4种类型,分别是
1、变量
变量语法:
{{ 变量 }}
变量解析规则:如book.name,会按照下列顺序解析:
1、字典book["name"]
2、先属性后方法,将book当做对象,查找属性name,如果没有就继续查找name()方法。
3、格式为book.0则解析为列表book[0]。
如果变量不存在,插入空字符串。在模板中调用方法时不能传递参数,如果要是用传递参数的方法,需要使用过滤器。
2、标签
标签语法:
{% 代码段 %}
常用标签:
for循环标签:
{% for item in 列表 %} 执行循环逻辑 {{ forloop.counter }}获取当前是第几次循环,从1开始 {% empty %} 列表为空或不存在时执行此逻辑 {% endfor %}
if标签:
{% if ... %} 逻辑1 {% elif ... %} 逻辑2 {% else %} 逻辑3 {% endif %}
比较远算符标签:
运算符左右两侧必须有空格:
== != < > <= >=
注意:运算符两侧不能紧挨变量或常量
布尔运算符标签:
and or not
3、过滤器(也可以自定义)
1、过滤器作用:模板语言中不允许带参数的函数,如果要对变量进行处理,就需要使用过滤器
2、使用管道符号 | 来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中
过滤器语法:
一个参数时:变量|过滤器
两个参数时:变量|过滤器:参数
第一个参数就是变量,如果过滤器需要追加参数,则使用:传递参数,冒号后面可以多传一个参数。
常用过滤器:
length,返回字符串、列表、元组、字典的元素个数 变量|length default,如果变量不存在时则返回默认值 变量|default:默认值 date,用于对日期类型的值进行字符串格式化 常用的格式化如下 Y表示年,格式为4位,y表示两位的年 m表示月,格式为01,02,12等 j表示日,格式为1,2等 H表示时,24进制,h表示12进制的时 i表示分,为0-59 s表示秒,为0-59 日期|date:'Y年m月j日 H时i分s秒'
过滤器演示
urls.py
path('filter/', views.filter),
views.py
#过滤器的演示 def filter(request): #获取全部书籍信息 booklist = Books.objects.all() content = {"booklist":booklist} return render(request,"Book/filter.html",content)
templates/Book/filter.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>过滤器演示</title> </head> <body> <ul> {% for book in booklist %} {% if book.name|length > 4 %} <li style="background: red">{{ book.name }}---------{{ book.pub_data|date:"Y-m-d" }}</li> {% else %} <li>{{ book.name }}-------{{ book.pub_data }}</li> {% endif %} {% endfor %} </ul> </body> </html>
当内建的过滤器不能满足我们使用的时候,需要自定义过滤器。过滤器就是python中的函数。
自定义过滤器
需求:循环到奇数时,内容背景为红色
循环到偶数时,内容背景为绿色
urls.py:
path('auto_filter/', views.auto_filter),
views.py
#自定义过滤器的使用 def auto_filter(request): #获取书籍全部信息 booklist = Books.objects.all() content = {"booklist":booklist} return render(request,"Book/auto_filter.html",content)
自定义奇数偶数的过滤器:1、在Book应用目录下创建python package包(templatetags),2、在包下新建py文件用于定义过滤器函数。
自定义过滤器函数:
#导入注册模块 from django.template import Library #创建注册对象,命名为register register = Library() #把以下函数注册成过滤器 @register.filter #定义求奇数偶数的函数 def mod(num): #返回的0,1代表False和True return num%2
模板:需要在模板中使用load标签加载自定义的过滤器:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>自定义过滤器</title> </head> <body> {#需要加载自定义的过滤器#} {% load auto_filter %} <ul> {% for book in booklist %} {#奇数执行的逻辑#} {% if forloop.counter|mod %} <li style="background: green">{{ book.name }}</li> {#偶数执行逻辑#} {% else %} <li style="background: red">{{ book.name }}</li> {% endif %} {% endfor %} </ul> </body> </html>
自定义接收多个参数的过滤器
自定义对任意整数求余数的过滤器(auto_filter.py)
@register.filter def mod1(num1,num2): #余数为0返回False,反之True return num1%num2
模板:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>自定义过滤器</title> </head> <body> {#需要加载自定义的过滤器#} {% load auto_filter %} <ul> {% for book in booklist %} {% if forloop.counter|mod1:3 %} {#执行不为0的逻辑#} <li style="background: green">{{ book.name }}</li> {#执行0的逻辑#} {% else %} <li style="background: red">{{ book.name }}</li> {% endif %} {% endfor %} </ul> </body> </html>
效果图:
必须注意的事项:
1.自定义过滤器的python包,必须命名为templatetags 2.创建注册对象,必须命名为register 3.过滤器的第一个参数就是变量,当有第二个参数时,后面需要使用冒号,最多只能传二个参数
4、注释
就是不会编译的内容,(html注释只能注释html。不能注释模板语言)
语法
单行注释语法如下 {#...#} 多行注释使用comment标签,语法如下 {% comment %} ... {% endcomment %}
模板继承
典型应用:网站的头尾信息
父模板
这段代码会多次出现,为了减少开发的重复,就把这段代码内容定义到父模板中。在父模板中也可以使用上下文传递过来的数据。
定义在templates文件目录下
使用到的标签block标签:用于在父模板中预留的区域,留给字模板填充一些不同的内容。
语法:
{% block 名称 %}
预留区域,可以编写默认内容,也可以没有默认内容
{% endblock 名称 %}
子模板
定义在templates/应用名文件目录下。
extends标签:继承,写在子模板文件的第一行。
只需要填充自己想要不同的页面的预留区域。
语法:
{% block 名称 %}
实际填充内容
{{ block.super }} 用于获取父模板中block的内容,也可以不获取
{% endblock 名称 %}
演示:
文件目录展示:
父模板:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>父模板</title> </head> <body> {% block top %} <h1>这是网页头部</h1> {% endblock top %} {% block content1 %} <div>啦啦啦啦啦</div> {% endblock content1 %} {% block content2 %} {#预留区域#} {% endblock content2 %} {% block bottom %} <h1>这是网页尾部</h1> {% endblock bottom %} </body> </html>
匹配url:
path("jiceng/",views.jicheng)
视图
# 模板继承 def jicheng(request): # 获取数据库书籍列表信息 booklist = Books.objects.all() # 构造上下文 content = {'booklist': booklist} return render(request, 'Book/jicheng.html', content)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>子模板</title> </head> <body> {#继承父模板#} {% extends 'base.html' %} {% block content2 %} <ul> {% for book in booklist %} <li>{{ book.name }}</li> {% endfor %} </ul> {% endblock content2 %} </body> </html>
必须注意的地方:
1.父模板定义在templates文件目录下 2.子模板定义在templates/应用文件目录下 3.子模版继承父模板之后,本身原有的内容是不起作用的 4.父模板不能把上下文传给子模板,只继承内容不继承上下文