python学习第9天---django框架---模板详解
目录
文章目录
内容
1、模板的功能
&emps;模板用于生产html,控制页面展示的内容。模板文件不仅仅是html文件,模板文件包含2部分内容:
- 静态内容:js、css、img等等静态资源
- 动态内容:用于动态生成一些页面内容,通过模板语言
2、模板文件的使用
2.1、使用步骤
通常是通过视图函数使用模板生成html内容返回给客户端,步骤如下:
- 加载模板文件:loader.get_template,获取模板文件内容,生成一个模板对象
- 定义模板上下文:Context,给模板文件传递数据
- 模板渲染产生html页面:render,用传递的数据替换模板文件中的响应变量,生成替换后的html文件。
2.2、示例
接上面书籍管理系统,我们把书籍管理系统登录后书籍管理首页及视图函数,稍加修改。
-
模板文件代码2.2-1:index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .book { width: 200px; height: 100px; margin: 0 auto; } li { color: green; } </style> </head> <body> <div class="book"> <h3 style="color: orange">{{ title }}首页</h3> <hr> <a href="http://127.0.0.1:8000/book/book_list">{{ content }}</a> </div> </body> </html>
-
视图函数代码2.2-2:index
def index(request): # return HttpResponse('欢迎进入书籍管理系统') # 1、加载模板文件,生成模板对象 temp = loader.get_template('book/index.html') # 2、定义模板上下文,给模板文件传递数据 content = {'title': '书籍管理', 'content': '书籍列表'} context = Context(content) # 3、模板渲染,替换模板文件中响应变量,返回html内容 res_html = temp.render(content, request) # 4、返回应答 return HttpResponse(res_html)
-
效果图示2.2-1:
2.3、封装
render函数其实已经帮我们封装好了,直接使用就好了。代码2.3-1:
def index(request):
# return HttpResponse('欢迎进入书籍管理系统')
return render(request, 'book/index.html', {'title': '书籍管理', 'content': '书籍列表'})
结果与2.2相同,有兴趣的小伙伴可以自己去查看render源代码。
3、模板文件的加载顺序
-
首先去配置的模板目录下面找模板文件
-
当前配置目录:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # 当前配置模板目录 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, },
]
-
-
去INSTALL_APPS下面的每个应用中去找模板文件,前提是应用中必须有templates文件夹
-
INSTALL_APPS:
INSTALLED_APPS = [ 'django.contrib.admin', # 有templates目录 'django.contrib.auth', # 有templates目录 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'book', # book应用 'login', # 登录应用 ]
-
4、模板语言
4.1、模板变量
- 命名:由字母、数字和下划线组成,不能以下划线开头。
- 使用:{{ var_name }}
- 示例代码:查看2.2-1代码
4.2、模板标签
4.2.1、 循环:
-
模板示例:
{% for book in book_list %} 代码块 {% endfor %}
4.2.2、判断
-
模板示例:
{% if 判断条件 %} ... {% elif 判断条件 %} ... {% else %} ... {% endif %}
4.3、过滤器
过滤器用于对模板变量操作。
- 格式:模板变量 | 过滤器: 参数
4.3.1、常用内置过滤器
- date:改变日期的显示格式
- length:求长度。字符串,元组,列表,字典。
- default:设置模板变量的默认值。
详细参数可以参考官方文档,地址:https://docs.djangoproject.com/en/3.0/
4.3.2、自定义过滤器
过滤器本身是python函数一种。我们在自定义python函数后,需要注册才能成为过滤器函数,并且前端页面加载后,才可以同内置过滤器一样使用。
-
步骤:
-
在应用下创建目录templatetags目录
-
templatetags目录下新建自定义过滤器文件filters.py(文件名非固定)
-
编辑文件filters.py
-
代码4.3.2-1:
# 自定义过滤器 from django import template # 创建Library对象 register = template.Library() # register固定名称 @register.filter(name='isEven') # name可省略,默认过滤器名字为函数名 def isEven(num): """判断一个数是否是偶数""" return num % 2 == 0
-
-
settings.py中注册
-
代码:4.3.2-2:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], 'libraries': { # 自定义过滤器 'filters': 'book.templatetags.filters' }, }, }, ]
-
-
前端文件加载过滤器文件filters.py
-
book_list_filter.html代码4.3.2-3:
<!DOCTYPE html> <html lang="en"> {% load filters %} <head> <meta charset="UTF-8"> <title>图书管理系统</title> <style> .test { width: 550px; height: 100px; margin: 0 auto; } li { color: green; } </style> </head> <body> <div class="test"> <h3 style="color: orange">书籍管理首页</h3> <hr/> <table border="1"> <thead> <tr> <th>ID</th> <th>书籍名称</th> <th>出版时间</th> <th>阅读量</th> <th>评论量</th> <th>是否在售</th> <th>书籍简介</th> </tr> </thead> <tbody> {% for book in book_list %} {% if book.id|isEven %} <!--自定义过滤器 --> <tr style="color: red"> <td>{{ book.id }}</td> <td>{{ book.name}}</td> <td>{{ book.publishing_date|date:"Y/m/d"}}</td> <td>{{ book.reading_volume}}</td> <td>{{ book.comment_volume}}</td> {% if book.isDelete %} <td>否</td> {% else %} <td>是</td> {% endif %} <td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td> </tr> {% else %} <tr style="color: green"> <td>{{ book.id }}</td> <td>{{ book.name}}</td> <td>{{ book.publishing_date|date:"Y/m/d"}}</td> <td>{{ book.reading_volume}}</td> <td>{{ book.comment_volume}}</td> {% if book.isDelete %} <td>否</td> {% else %} <td>是</td> {% endif %} <td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td> </tr> {% endif %} {% endfor %} </tbody> </table> <a href="http://127.0.0.1:8000/book/index">返回</a> </div> </body> </html>
-
-
使用-同内置过滤器
-
-
示例,根据书籍id的奇偶显示不同颜色。
- 图示4.3.2-1:
4.4、模板运算符
- 关系运算符:<,>,==,!=,<=,>=
- 逻辑运算符:and,or, not,in
tips:运算符前后要加空格,不然会报错
4.5、模板注释
-
单行注释:{# #}
-
多行注释:
{% comment %} ... {% endcomment
4.5、综合示例
根据书籍id,显示不同的颜色。id<=2时,显示红色;id<=4时,显示绿色;其他的显示蓝色。
-
示例代码4.5-1:book_list_structure.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>图书管理系统</title> <style> .test { width: 550px; height: 100px; margin: 0 auto; } li { color: green; } </style> </head> <body> <div class="test"> <h3 style="color: orange">书籍管理首页</h3> <hr/> <table border="1"> <thead> <tr> <th>ID</th> <th>书籍名称</th> <th>出版时间</th> <th>阅读量</th> <th>评论量</th> <th>是否在售</th> <th>书籍简介</th> </tr> </thead> <tbody> {% for book in book_list %} {% if book.id <= 2 %} <tr style="color: red"> <td>{{ book.id }}</td> <td>{{ book.name}}</td> <td>{{ book.publishing_date|date:"Y/m/d"}}</td> <td>{{ book.reading_volume}}</td> <td>{{ book.comment_volume}}</td> {% if book.isDelete %} <td>否</td> {% else %} <td>是</td> {% endif %} <td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td> </tr> {% elif book.id <= 4 %} <tr style="color: green"> <td>{{ book.id }}</td> <td>{{ book.name}}</td> <td>{{ book.publishing_date|date:"Y/m/d"}}</td> <td>{{ book.reading_volume}}</td> <td>{{ book.comment_volume}}</td> {% if book.isDelete %} <td>否</td> {% else %} <td>是</td> {% endif %} <td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td> </tr> {% else %} <tr style="color: blue"> <td>{{ book.id }}</td> <td>{{ book.name}}</td> <td>{{ book.publishing_date|date:"Y/m/d"}}</td> <td>{{ book.reading_volume}}</td> <td>{{ book.comment_volume}}</td> {% if book.isDelete %} <td>否</td> {% else %} <td>是</td> {% endif %} <td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td> </tr> {% endif %} {% endfor %} </tbody> </table> <a href="http://127.0.0.1:8000/book/index">返回</a> </div> </body> </html>
-
视图函数代码4.5-2:
def book_list_structure(request): '''书籍列表展示''' books = Book.objects.all() return render(request, 'book/book_list_structure.html', {'book_list': books})
-
url: url(r’^book_list_structure$’, views.book_list_structure),
-
效果图示4.5-1:
6、模板继承
通常网站都有一些通用的网页部分,比如头部导航和底部版权信息。如果,所有页面都写一遍,增加很多工作量。这里使用模板继承很方便。
-
父模板:公用模板
-
格式:
# 相同内容 ... # 不同内容 {% block 块名1 %} ... {% endblock 块名1 %} {% block 块名2 %} ... {% endblock 块名2 %} ... ...
-
解析:
- 对于通用的内容,即为普通的html
- 不同的内容包裹在block块内
- 可以有多个block块
-
-
子模板:继承子父模板
-
格式
{% extends 父模板 %} {% block 块名1 %} ... {% endblock 块名1 %} {% block 块名2 %} ... {% endblock 块名2 %}
-
解析:
- 子模板可以重新块中的内容,也可以使用父模板原有的内容
- block.super为父模板块中内容
-
-
示例:pass
7、html转义
模板上下文中的html标记默认是会被转义的。常见对应关系表格7-1:
显示 | 说明 | html编码 | 16进制编码 |
---|---|---|---|
半方大的空白 |   |   | |
全方大的空白 |   |   | |
不断行的空白格 | |   | |
< | 小于 | < | < |
> | 大于 | > | > |
& | &符号 | & | & |
" | 双引号 | " | " |
© | 版权 | © | © |
® | 已注册商标 | ® | ® |
™ | 商标(美国) | \™ | ™ |
× | 乘号 | × | × |
÷ | 除号 | ÷ | ÷ |
- 关闭自动转义
-
单行关闭:
{{ 模板变量|safe}}
-
多行关闭:
{% autoescape off %} ... {% endautoescape %}
-
感兴趣的小伙伴可以自行搜索,这里不再详述。
后记 :
本项目为参考某音python系列视频。上面为自己参考写的学习笔记,持续更新。欢迎交流,本人QQ:806797785