目录
介绍
模版是可以让开发者将后端数据填充到html页面中并渲染,在templates创建模版才可以在视图做绑定,静态页面是指写死的一个页面没有动态数据,动态页面页面是指使用占位符等将相关数据展示渲染到页面 模版DTL官网,
settings配置模版路径
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [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',
],
},
},
]
render函数内部本质
def index(request):
"""
# 第一步获取文件
tem = get_template("app01/index.html")
# 第二步获取数据
content ={"name": "zhq"}
# 第三步渲染
html = tem.render(content,request)
print("aaaa",html)
return HttpResponse(html)
"""
return render(request,"app01/index.html",{"name": "zhq"}) # 这一行代码替代以上是哪个步骤,这一行和上面效果相同
深度查询
获取列表数据 句点符.
- 视图
def index(request): bobby_list = ["篮球","游泳","羽毛球","钓鱼"] return render(request,"app01/index.html",locals()) # locals 是将局部变量全部自动传给模版,局部变量要和模版的占位符变量相同
- 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>深度查询</h3> <p>爱好:{{ bobby_list }}</p> # 获取列表数据 <p>爱好一:{{ bobby_list.0 }}</p> # 获取列表的某一个数据格式是 变量.0 意思就是获取列表的第一个数据索引是从0开始 <p>爱好二:{{ bobby_list.1 }}</p> </body> </html>
获取字典数据 句点符.
- 视图
def index(request): lisi = {"name":"lisi","age":25,"addr":"上海"} return render(request,"app01/index.html",locals()) # locals 是将局部变量全部自动传给模版,局部变量要和模版的占位符变量相同
- 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>深度查询</h3> <p>个人详情信息:{{ lisi }}</p> <p>姓名:{{ lisi.name }}</p> # 获取字典的某一个数据格式是 变量.key 意思就是获取字典数据变量.字典的键 <p>年龄:{{ lisi.age }}</p> <p>地址:{{ lisi.addr }}</p> </body> </html>
获取对象属性 句点符.
- 视图
class Book(object): def __init__(self, title, price): self.title = title self.price = price def __str__(self): return self.title def index(request): book = Book("心灵鸡汤","198") return render(request, "app01/index.html", locals()) # locals 是将局部变量全部自动传给模版,局部变量要和模版的占位符变量相同
- 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>深度查询</h3> <p>书名:{{ book.title }}</p> # 获取对象属性格式是 变量.属性名,就是变量.类里面的属性名称 <p>价格:{{ book.price }}</p> </body> </html>
获取嵌套数据 句点符.
- 视图
class Book(object): def __init__(self, title, price): self.title = title self.price = price def __str__(self): return self.title def index(request): book1 = Book("心灵鸡汤","198") book2 = Book("三国","289") book3 = Book("西游记","398") book4 = Book("python","489") books = [book1, book2, book3, book4] return render(request, "app01/index.html", locals()) # locals 是将局部变量全部自动传给模版,局部变量要和模版的占位符变量相同
- 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>深度查询</h3> <p>第二本书的名称:{{ books.1.title }}</p> # 当获取嵌套数据的时候,可以直接变量名.索引.属性名称 <p>第二本书的价格:{{ books.1.price }}</p> </body> </html>
过滤器
过滤器格式:{{obj|过滤器名称:过滤器参数}}更多详情见
Django内部过滤器
-
first
获取第一个数据- 视图
class Book(object): def __init__(self, title, price): self.title = title self.price = price def __str__(self): return self.title def index(request): book1 = Book("心灵鸡汤","198") book2 = Book("三国","289") book3 = Book("西游记","398") book4 = Book("python","489") books = [book1, book2, book3, book4] return render(request, "app01/index.html", locals())
- 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Django 内置过滤器</h3> <p>获取books最后一本数:{{ books | first | title }}</p> </body> </html>
使用过滤器的格式是{{obj|过滤器名称:过滤器参数}},第一个是变量名,第二个是过滤器,第三个是参数,就比如上面案例他传入的是一个列表里面有多个对象,第一个是占位符 第二个是过滤器,first是Django内部的一个过滤器,代表获取第一个值,第三个是参数是 比如我获取到第一个对象后在获取该对象的属性
- 视图
-
last
获取最后一个数据- 视图
class Book(object): def __init__(self, title, price): self.title = title self.price = price def __str__(self): return self.title def index(request): book1 = Book("心灵鸡汤","198") book2 = Book("三国","289") book3 = Book("西游记","398") book4 = Book("python","489") books = [book1, book2, book3, book4] return render(request, "app01/index.html", locals())
- 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Django 内置过滤器</h3> <p>获取books最后一本数:{{ books | last | title }}</p> </body> </html>
使用过滤器的格式是{{obj|过滤器名称:过滤器参数}},第一个是变量名,第二个是过滤器,第三个是参数,就比如上面案例他传入的是一个列表里面有多个对象,第一个是占位符 第二个是过滤器,last是Django内部的一个过滤器,代表获取最后一个值,第三个是参数是 比如我获取到最后一个对象后在获取该对象的属性
- 视图
-
date
日期时间格式转换- 视图
def index(request): import datetime now = datetime.datetime.now() return render(request, "app01/index.html", locals())
- 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Django 内置过滤器</h3> <p>日期:{{ now | date:"Y-m-d" }}</p> # 年-月-日 <p>详细日期:{{ now | date:"Y-m-d H:i:s" }}</p> # 年-月-日 时:分: 秒 </body> </html>
- 视图
-
filesizeformat
将文件大小的值转换成 单位展示如 :'13 KB'、'4.1 MB'、'102 bytes' 等
- 视图
def index(request): filesize = 122223333 # 字节 return render(request, "app01/index.html", locals())
- 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Django 内置过滤器</h3> <p>文件大小:{{ filesize | filesizeformat }}</p> # 使用filesizeformat后 116.6 MB </body> </html>
- 视图
-
safe
标记一个字符串在输出前不需要进一步的 HTML 转义- 视图
def index(request): link = "<a href='http://www.baidu.com'>baidu<a>" return render(request, "app01/index.html", locals())
- 模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Django 内置过滤器</h3> <p>链接:{{link | safe}}</p> # 也就是说不加safe会将 一个html标签当成字符串输出,加上会当成一个标签输出, </body> </html>
- 视图
-
length
获取长度<p>books一共有{{ books | length }}本书</p> # 细节和上面相同
-
default
如果值为 False,则使用给定的默认值。否则,使用该值。<p>books2展示 {{ books2 | default:"books2没有符合的条件的书籍" }}本书</p> # 当books为False没有数据的时候 给一个默认值
Django自定义过滤器
- 自定义过滤器 首先要检查settings里面是否注册app
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', # 一般都是默认注册的 如果没有注册手动添加即可 ]
- 在子应用创建templatetags包[必须包含__init__.py], 在包目录下创建任意py文件 也可以在全局创建一般都是在子应用创建,好区分是哪个应用的templatetags
- 在templatetags创建一个py文件,用于存放自己的过滤器,也可以创建多个
from django import template # 导入template register = template.Library() # 注册,构建一个注册对象 @register.filter(name='mobile') # 标记函数是一个过滤器 name='mobile'这个名称随便写 这个name就是在模版里面调用的name 可以在模版里面使用mobile def mobile(content): return content[0:3]+"*****"+content[-3:]
- 使用自定义过滤器
{% load my_filters %} # 想使用内置的过滤器,在模版文件的上方需要加载过滤器,my_filters就是存放过滤取的py文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Django 内置过滤器</h3> <p>手机号:{{ mob | mobile }}</p> </body> </html>
标签
标签在渲染过程中提供了任意逻辑。内置模版标签官网文档 | 自定义标签编写指南 |
这个定义是故意含糊的。例如,标签可以输出内容,或用作控制结构如 “if” 语句和 “for” 循环,或从数据库中抓取内容,甚至可以访问其他模板标签。
if标签
- 模版使用if
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Django if标签</h3> {% if performance >= 90 %} <p>成绩优秀</p> {% elif performance >= 80 %} <p>成绩良好</p> {% elif performance >= 60 %} <p>成绩一般</p> {% else %} <p>成绩不及格</p> {% endif %} # 判断最后必须加{% endif %} </body> </html>
- 视图
def index(request): performance = 54 return render(request, "app01/index.html", locals())
for标签
for 循环有个forloop对象 forloop只能在for标签里面使用 拿到外面无效
变量名 | 描述 |
---|---|
forloop.counter | 循环计数器,表示当前循环的索引(从 1 开始)。 |
forloop.counter0 | 循环计数器,表示当前循环的索引(从 0 开始)。 |
forloop.revcounter | 反向循环计数器(以最后一次循环为 1,反向计数)。 |
forloop.revcounter0 | 反向循环计数器(以最后一次循环为 0,反向计数)。 |
forloop.first | 当前循环为首个循环时,该变量为 True |
forloop.last | 当前循环为最后一个循环时,该变量为 True |
forloop.parentloop | 在嵌套循环中,指向当前循环的上级循环 |
- 模版使用for
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Django for标签</h3> <table width="1000" border="1"> <tr> <td>序号</td> <th>书籍名称</th> <th>价格</th> <th>详情</th> </tr> {% for book in books %} {% if book.price > 300 %} <tr> <th>{{ forloop.counter }}</th> <th>{{ book.title }}</th> <th style="color: red">{{ book.price }}</th> <th>{{ book.details }}</th> </tr> {% else %} <tr> <td>{{ forloop.counter }}</td> <th>{{ book.title }}</th> <th>{{ book.price }}</th> <th>{{ book.details }}</th> </tr> {% endif %} {% endfor %} </table> </body> </html>
- 视图
from django.shortcuts import render class Book(object): def __init__(self, title, price,details): self.title = title self.price = price self.details = details def __str__(self): return self.title def index(request): book1 = Book("python",199,"本书讲解了python2会让python3") book2 = Book("pytest",299,"解刨pytest") book3 = Book("mysql",399,"解刨mysql") book4 = Book("Django",499,"解刨Django") books = [book1,book2,book3,book4] return render(request, "app01/index.html", locals())
- 效果
include标签 加载另外一个模版到当前模版中渲染
include标签 加载另外一个模版到当前模版中渲染 模版分离技术可以使用{% include "模版名称"%} 来实现,将不同页面的共同的地方提取出来 在使用的时候 直接使用 {% include "模版名称"%} 来加载到当前模版 这样也大大提高了代码的复用性
-
父模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .advertise{ width: 200px; height: 200px; background-color: lavender; position: fixed; bottom: 10px; right: 10px; } </style> </head> <body> <div class="advertise">广告</div> </body> </html>
-
子模版
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>我的订单</h3> <ul> {% for order in order_list %} <li>{{ order }}</li> {% endfor %} </ul> {% include "app01/ad.html" %} # 哪里想使用父模版 在哪里直接使用 {% include "app01/ad.html" %} 加载即可 </body> </html>
继承
继承就是子页面继承父页面,比如写一个base页面 在子页面继承,{% block content %} 盒子可以写多个
- base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> {% block title %} # 这是一个title盒子 <title>Title</title> {% endblock %} </head> <body> <div>base 页面的内容</div> <div class="panel panel-default col-md-10" > {% block content %} # 等于是开一个盒子 可以被继承的页面改变这块内容 content 是这个盒子的名字 <p>默认值</p> # 默认值当继承的页面内容为空将会展示默认值 {% endblock %} </div> </body> </html>
- 子页面
{% extends "app01/base.html" %} # 表示继承一个父模版 必须将导入写到用到盒子的文件上面。一般写到最上方 {% block title %} <title>首页</title> {% endblock %} {% block content %} # 使用盒子 content 意思是将内容替换到哪个盒子 <p>你好</p> # 会将该内容写到 父模版里面的 content盒子里面 {% endblock %}