1. 模板的功能
产生html,控制页面上展示的内容。模板文件不仅仅是一个html文件。
模板文件包含两部分内容:
1) 静态内容:css,js,html。
2) 动态内容:用于动态去产生一些网页内容。通过模板语言来产生。
2. 模板文件的使用
通常是在视图函数中使用模板产生html内容返回给客户端。
a) 加载模板文件 loader.get_template
获取模板文件的内容,产生一个模板对象。
b) 定义模板上下文 RequeseContext
给模板文件传递数据。
c) 模板渲染产生html页面内容 render
用传递的数据替换相应的变量,产生一个替换后的标准的html内容。
案例
1.为了测试重新创建一个项目和应用,由于前面已经创建了虚拟环境,这里就直接创建项目和应用了。
cmd命令:
D:\pyweb\python-web>django-admin startproject testday04
D:\pyweb\python-web\testday03>python manage.py startapp booktest
2.然后使用pycharm打开项目创建templates和static文件夹,然后配置应用:
# 新增和修改以下代码
INSTALLED_APPS = [
....
'booktest', # 注册应用
]
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, "templates")],# 配置模板路径
...
},
]
# 配置mysql数据库
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default': {
'ENGINE': 'django.db.backends.mysql', # 使用mysql数据库
'NAME': "booktest", # 使用test数据库名称,必须手动创建
'USER': "root", # mysql用户名
'PASSWORD': "root", # mysql密码
'HOST': "localhost", # 指定mysql数据库的电脑ip,本地直接写localhost
'PORT': 3306, # mysql端口
}
}
# 配置静态文件保存目录
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
3.在__init__导入mysql模块
import pymysql
pymysql.install_as_MySQLdb()
4.启动应用测试是否成功
# 启动命令
D:\pyweb\python-web\testday03>python manage.py runserver
5.配置testday02的urls文件
from django.contrib import admin
from django.urls import path,include
from django.conf.urls import url
from booktest import urls
urlpatterns = [
path('admin/', admin.site.urls),
url(r"^", include(urls)) # url书写方式,这种形式可以练习正则表达式
]
6.在booktest应用中创建一个urls.py文件,写下如下代码:
from django.conf.urls import url
from booktest import views
urlpatterns = [
# 配置index视图方法
url(r"^index$", views.index)
]
7.index.html模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{result}}
</body>
</html>
8.view.py视图文件
from django.shortcuts import render
from django.template import loader, RequestContext
from django.http import HttpResponse
# 自定义render函数
def my_render(request, templeta_path, context={}):
# 1.加载模板文件,获取一个模板对象
temp = loader.get_template(templeta_path)
# 2.定义一个模板上下文,给模板传递数据
# context = RequestContext(request, context)# 如果django是1.11版本这样写会报错:
# 3.模板渲染,产生一个替换后的html内容
render_html = temp.render(context)
# 4.返回httpresponse
return HttpResponse(render_html)
def index(request):
# 使用内置的模板render函数
# return render(request, "booktest/index.html", {"result": "模板文件显示"})
return my_render(request, "booktest/index.html", {"result": "模板文件显示"})
9.再次启动
# 启动命令
D:\pyweb\python-web\testday03>python manage.py runserver
3.模板文件加载顺序
1) 首先去配置的模板目录下面去找模板文件。
2) 去INSTALLED_APPS下面的每个应用的templates去找模板文件,前提是应用中必须有templates文件夹。
4.模板变量
模板变量的作用是计算并输出,变量名必须由字母、数字、下划线(不能以下划线开头)和点组成。
语法如下:
{{变量}}
当模版引擎遇到点如book.title,会按照下列顺序解析:
1.字典book['title']
2.先属性后方法,将book当作对象,查找属性title,如果没有再查找方法title()
3.如果是格式为book.0则解析为列表book[0]
1) 首先把book当成一个字典,把0当成键名,进行取值book[0]
2) 把book当成一个列表,把0当成下标,进行取值book[0]
注意:如果变量不存在则插入空字符串''。并且使用模板变量时,.前面的可能是一个字典,可能是一个对象,还可能是一个列表。在模板中调用方法时不能传递参数。
5.模板标签
{% 代码段 %}
for循环:
{% for x in 列表 %}
# 列表不为空时执行
{% empty %}
# 列表为空时执行
{% endfor %}
可以通过{{ forloop.counter }}得到for循环遍历到了第几次。
{% if 条件 %}
{% elif 条件 %}
{% else %}
{% endif %}
关系比较操作符:> < >= <= == !=
注意:进行比较操作时,比较操作符两边必须有空格。
逻辑运算:not and or
6.过滤器
过滤器用于对模板变量进行操作。
格式:模板变量|过滤器:参数
date:改变日期的显示格式。
{{bdate_value | date:'Y年-m月-d日'}}
length:求长度。字符串,列表.
{{btitle_value | length}}
default:设置模板变量的默认值。
{{bitle_value | default:"默认值"}}
自定义过滤器
自定义的过滤器函数,至少有一个参数,最多两个
views.py
# 自定义过滤器模板显示
def temp_filter(request):
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
return my_render(request, "booktest/temp_filter.html", {"list1":list1})
urls.py
url(r"^temp_filter$", views.temp_filter)
在booktest应用中创建一个templatetags文件夹,在文件夹中创建filters.py
filters.py
# 自定义过滤器
# 过滤器其实就是python函数
from django.template import Library
# 创建一个Librar对象
register = Library()
# 自顶一个过滤器set_num判断整除
@register.filter
def set_num1(num, val):
# 判断num是否能被val整除
return num % val == 0
@register.filter
def set_num2(num):
# 判断num是否能被val整除
return num % 2 == 0
temp_filter.html
<!DOCTYPE html>
<html lang="en">
{% load filters %}
<head>
<meta charset="UTF-8">
<title>过滤器</title>
</head>
<body>
循环
<ul>
{% for index in list1 %}
{# {% if index|set_num1:2 %} #}
{% if index|set_num2 %}
<li>{{index}}</li>
{% endif %}
{% endfor %}
</ul>
</body>
</html>
注意:创建templatetags文件夹时,文件夹名称一个都不能错,另外在temp_filter.html中需要加载自定义过滤器{% load filters %},这是加载所有自定义过滤器
参考资料:(模板标签和内置过滤器)
http://python.usyiyi.cn/documents/django_182/ref/templates/builtins.html
7.模板注释
单行注释:{# 注释内容 #}
多行注释:{% comment %}
注释内容
{% endcomment %}
8.模板继承
模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。
典型应用:网站的头部、尾部信息。
父模板
如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。
标签block:用于在父模板中预留区域,留给子模板填充差异性的内容,名字不能相同。为了更好的可读性,建议给endblock标签写上名字,这个名字与对应的block名字相同。父模板中也可以使用上下文中传递过来的数据。
{%block 名称%}
预留区域,可以编写默认内容,也可以没有默认内容
{%endblock 名称%}
子模板
标签extends:继承,写在子模板文件的第一行。
{% extends "父模板路径"%}
子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值。
填充父模板中指定名称的预留区域。
{%block 名称%}
实际填充内容
{{block.super}}用于获取父模板中block的内容
{%endblock 名称%}
实例:
views.py
# 模板继承视图显示方法
def show_template1(request):
return render(request, "booktest/child1.html")
# 模板继承视图显示方法
def show_template2(request):
return render(request, "booktest/child2.html")
urls.py
url(r"^show1$", views.show_template1),
url(r"^show2$", views.show_template2),
parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父模板</title>
</head>
<body>
<h1>头部</h1>
{% block child%}
<h4>预留子模块</h4>
{% endblock child%}
<h1>底部</h1>
</body>
</html>
child1.html
{% extends "booktest/parent.html" %}
{% block child %}
<h5>child1子模块继承并且重写成功</h5>
{% endblock child %}
child2.html
{% extends "booktest/parent.html" %}
{% block child %}
<h5>child2子模块继承并且重写成功</h5>
{% endblock child %}
启动应用:
python manage.py runserver
浏览器输入:
http://127.0.0.1:8000/show1
http://127.0.0.1:8000/show2
9.html转义
编辑商品详情信息,数据表中保存的是html内容。
在模板上下文中的html标记默认是会被转义的。
小于号< 转换为<
大于号> 转换为>
单引号' 转换为'
双引号" 转换为 "
与符号& 转换为 &
要关闭模板上下文字符串的转义:可以使用 {{ 模板变量|safe}}
也可以使用:
{% autoescape off %}
模板语言代码
{% endautoescape %}
模板硬编码中的字符串默认不会经过转义,如果需要转义,那需要手动进行转义。