4.django-模板
在django中,模板引擎(DTL)是一种可以让开发者将服务端数据填充到html页面中的完成渲染的技术
模板引擎的原理分为以下三步:
在项目配置文件中指定保存模板文件的的模板目录,一般设置在项目根目录或者子应用目录下
在模板目录下创建对应的模板文件
在视图函数中通过render函数绑定模板文件和需要渲染的数据
1.模板目录
在简单的项目中,我们通常在项目的根目录下创建名为templates的文件夹,并在配置文件中设置模板目录
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',
],
},
},
]
如果是多app的情况下,我们不仅要设置主模板目录,还要在每个app下创建对应的templates,包含该子app所需要的模板文件
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',
],
},
},
]

提示:在使用模板的时候,django会到主模板目录下寻找,找不到会按照顺序到已注册的项目下的模板目录中寻找
简单案例
路由
from django.contrib import admin
from django.urls import path, include
from apps.app01 import views urlpatterns = [
path('admin/', admin.site.urls),
path('book/',views.index)
]
视图
def index(request):
return render(request, 'app01/index.html')
模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> </body>
</html>
2.render函数的本质
render函数的本质就是将模板文件中的所有变量替换成后端数据,生成一个html页面,也就是纯文本,响应给客户端
模板文件 & html页面的区别
模板文件是含有特殊语法的html文件,这个语法可以被django的DTL编译,将数据传进,实现动态话,渲染之后的模板文件也就是一个普通的html文件了 开发中我们常将普通的html称之为静态文件,将模板文件称之为动态文件
视图函数
def index(request):
name = 'kunmzhao'
return render(request, 'app01/index.html', {'name':name}) # 将数据传递给模板文件
模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ name }}</p> #含有模板语法
</body>
</html>
渲染之后的html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>kunmzhao</p> # 渲染之后
</body>
</html>
3.模板语法
3.1 句点符
变量渲染可以将对象原封不动的渲染在页面
def index(request):
# 字符串
name = 'kunmzhao'
# 数字
age = 18
# 列表
course = ['语文', '数学', '英语']
# 元组
hobby = ('篮球', '足球')
# 字典
parents = {'father': 'mayun', 'mother': "dongmingzhu"}
# 集合
teachers = {'alex', 'victor'} return render(request, 'app01/index.html', {
'name': name,
'age': age,
'course': course,
'hobby': hobby,
'parents': parents,
'teachers': teachers,
}

句点符就可以访问对象中的属性
from django.shortcuts import render, HttpResponse # Create your views here.
class Animal(object):
def __init__(self, name, age):
self.name = name
self.age = age def index(request):
# 字符串
name = 'kunmzhao'
# 数字
age = 18
# 列表
course = ['语文', '数学', '英语']
# 字典
parents = {'father': 'mayun', 'mother': "dongmingzhu"} # 对象
dog = Animal('rubby', 3) return render(request, 'app01/index.html', {
'name': name,
'age': age,
'course': course,
'parents': parents,
'dog': dog
}
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ name }}</p>
<p>{{ age }}</p>
<p>{{ course.0 }}</p> # 访问列表第几个元素
<p>{{ course.1 }}</p>
<p>{{ course.2 }}</p>
<p>{{ parents.father}}</p> # 访问字典中键对应的值
<p>{{ parents.mother }}</p>
<p>{{ dog.name }}</p> # 访问对象发的属性
<p>{{ dog.age }}</p> </body>
</html>
3.2 过滤器
3.2.1 内置过滤器
内置过滤器最多有一个参数
语法:
{{obj|过滤器名称:过滤器参数}}
| 过滤器 | 用法 | 代码 |
|---|---|---|
| last | 获取列表/元组的最后一个成员 | {{liast | last}} |
| first | 获取列表/元组的第一个成员 | {{list|first}} |
| length | 获取数据的长度 | {{list | length}} |
| defualt | 当变量没有值的情况下, 系统输出默认值, | {{str|default="默认值"}} |
| safe | 让系统不要对内容中的html代码进行实体转义 | {{htmlcontent| safe}} |
| upper | 字母转换成大写 | {{str | upper}} |
| lower | 字母转换成小写 | {{str | lower}} |
| title | 每个单词首字母转换成大写 | {{str | title}} |
| date | 日期时间格式转换 | {{ value| date:"D d M Y" }} |
| cut | 从内容中截取掉同样字符的内容 | {{content | cut:"hello"}} |
| list | 把内容转换成列表格式 | {{content | list}} |
| add | 加法 | {{num| add}} |
| filesizeformat | 把文件大小的数值转换成单位表示 | {{filesize | filesizeformat}} |
join |
按指定字符拼接内容 | {{list| join("-")}} |
random |
随机提取某个成员 | {list | random}} |
slice |
按切片提取成员 | {{list | slice:":-2"}} |
truncatechars |
按字符长度截取内容 | {{content | truncatechars:30}} |
truncatewords |
按单词长度截取内容 | 同上 |
def index(request):
name = 'kunmzhao'
hobby = ['篮球', '足球'] return render(request, 'app01/index.html', {
'name': name,
'hobby': hobby,
}
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ name|upper }}</p>
<p>{{ hobby|first }}</p>
<p>{{ hobby|last }}</p>
</body>
</html>
3.2.2 自定义过滤器
内置的过滤器可能没办法满足开发需求,django中支持使用自定义的过滤器
确保定义过滤器所在的app已经注册
在注册的app下创建templatetags的模块包

创建py文件
在文件中自定义过滤器
from django import template register = template.Library() # 自定义过滤器
@register.filter()
def mobile(content):
return content[:3] + "*****" + content[-3:]- 在模板中load过滤器并使用
{% load my_filter %} # 导入自定义的过滤器 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ phone|mobile }}</p> # 使用过滤器
</body>
</html>
3.3 标签渲染
3.3.1 if
语法:
{% if 条件 %}
{%endif %}
视图
def index(request):
score = 80
return render(request, 'app01/index.html', {
'score': score,
}
)
模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if score > 90 %}
<p>成绩优秀啊</p>
{% elif score > 80 %}
<p>成绩良好</p>
{% else %}
<p>成绩一般</p>
{% endif %}
</body>
</html>

3.3.2 for
语法
{% for i in iter %}
{%endfor %}
for标签中常用的方法
forloop.counter : 从1开始每次循环自增1
forloop.counter0 : 从0开始每次循环自增1
forloop.first : 是否是第一次循环
forloop.last : 是否是最后一循环
视图
def index(request):
hobby = ['篮球', '足球', '乒乓球']
return render(request, 'app01/index.html', {
'hobby': hobby,
}
)
模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for foo in hobby %} <p><span>{{ forloop.counter }}</span>{{ foo }}</p>
{% endfor %} </body>

4.模板自定义
- filter
见自定义过滤器
参数:1-2个 - Simple_tag
返回文本
参数:无限制 - Inclusion_tag
返回html片段
参数无限制
定义
# encoding:utf-8
# author:kunmzhao
# email:1102669474@qq.com
from django import template register = template.Library() # 自定义过滤器
@register.filter()
def mobile(content):
return content[:3] + "*****" + content[-3:] # 自定义simple_tag
@register.simple_tag()
def mytag(a1, a2):
return a1 + a2 # 自定义inclusion_tag
@register.inclusion_tag("app01/menu.html")
def my_inclusion():
return {'name': 'kunmzhao', 'age': 18}
模板
{% load my_filter %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ phone |mobile }}</p> # 使用自定义的过滤器
<p>{% mytag 100 200 %}</p> # 使用自定义的tag函数
<p>{% my_inclusion %}</p> # 使用自定义的inclusion_tag
</body>
</html>
menu.html
<p>
<span>name={{ name }}</span>
<span>age={{ age }}</span>
</p>
5.模板继承和导入
{% include "模板文件名"%} # 模板嵌入
{% extends "base.html" %} # 模板继承
5.1 继承
语法
{%entends 模板文件%} # 继承指定的模板文件 {% block 名称 %} # 填充模板中的某一个block {% endblock %}
视图
def index(request):
return render(request, 'app01/header.html')
模板header.html
{% extends 'app01/index.html' %}
{% block body%}
<div>不畏浮云遮望眼,只缘身在最高层</div>
{% endblock %}
模板index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% block css %}
{# css样式 #}
{% endblock %}
</head>
<body>
{% block body %}
{# 内容填充 #}
{% endblock %}
</body>
</html>

5.2 导入
{% include 片段文件名%}
视图
def index(request):
return render(request, 'app01/header.html', {'name': 'kunmzhao', 'age': 18})
模板menu.html
<p>
<span>name={{ name }}</span>
<span>age={{ age }}</span>
</p>
模板header.html
{% extends 'app01/index.html' %}
{% block body %}
<div>不畏浮云遮望眼,只缘身在最高层</div>
{% include 'app01/menu.html' %} # 导入片段
{% endblock %}

6.静态文件
我们通常会将前端的css, js等代码发在app对应的static目录下,我们在模板中导入css或者js等代码的时候,引入{ %load static %}
跟templates类似,在多app下,我们通常会在每个app下创建一个static的文件夹,再创建对应app名字的文件件,将该app下使用的静态文件放在该目录


4.django-模板的更多相关文章
- Django模板与Vue.js冲突问题
参考: https://my.oschina.net/soarwilldo/blog/755984 方法1:修改vue.js的默认的绑定符号 Vue.config.delimiters = [&quo ...
- 在 Django 模板中遍历复杂数据结构的关键是句点字符
在 Django 模板中遍历复杂数据结构的关键是句点字符 ( . ). 实例二 mysit/templates/myhtml2.html修改如下 <!DOCTYPE html> <h ...
- python django 模板
1 用两个大括号括起来的文字{{person_name}} 称为变量 2 被 大括号和面分号包围的文件({% if ordered_warranty %})是模板标签 3 过滤器是用管道符(|) 和U ...
- django 模板中定义临时列表
<ul class="num_t clr"> {% for obj in ""|ljust:"10" %} <li> ...
- Django 模板中引用静态资源(js,css等)
Django 模板中免不了要用到一些js和CSS文件,查了很多网页,被弄得略晕乎,还是官网靠谱,给个链接大家可以自己看英文的. https://docs.djangoproject.com/en/1. ...
- Django模板-分离的模板
上一篇Django模板-在视图中使用模板最后的问题,我们需要把数据和展现分离开. 你可能首先考虑把模板保存在文件系统的某个位置并用 Python 内建的文件操作函数来读取文件内容. 假设文件保存在 E ...
- Django模板-在视图中使用模板
之前我们已经有了自己的视图mysite.views.py中,应该是这样子的 from django.http import HttpResponse import datetime def curre ...
- Django模板-模板标签
接着Django模板-基础知识继续写模板相关知识. if标签 {% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not ). 但是不允许在同一个 ...
- Django模板-基础知识
上一篇中带参数的URLconf虽然可以做到传参动态显示内容,但是最终现实的内容还是硬编码到Python代码中的 def hours_ahead(request,phours): try: phours ...
- 关于Django模板引擎的研究
原创博文,转载请注明出处. 以前曾遇到过错误Reverse for ‘*’ with arguments '()' and keyword arguments' not found.1其原因是没有给视 ...
随机推荐
- HBase概念入门
HBase简介 HBase基于Google的BigTable论文而来,是一个分布式海量列式非关系型数据库系统,可以提供大规模数据集的实时随机读写. 下面通过一个小场景认识HBase存储.同样的一个数据 ...
- 什么?MySQL 8.0 会同时修改两个ib_logfilesN 文件?
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 作者介绍:孙黎,GreatDB 认证DBA 问题现象 ...
- Dubbo-Adaptive实现原理
前言 前面我们已经分析Dubbo SPI相关的源码,看过的小伙伴相信已经知晓整个加载过程,我们也留下两个问题,今天我们先来处理下其中关于注解Adaptive的原理. 什么是@Adaptive 对应于A ...
- multiprocessing 让子进程忽略信号,手动关闭子进程
起因 同事想要写一个代码,主进程中监听SIGINT.SIGTERM信号退出,并关闭启动的子进程,代码类似这样 import signal import sys import time from mul ...
- 用【Unity】中的【3D Object】画【数学函数】图形 —— 正弦函数... { }
效果 场景搭建 创建一个空物体,并将其命名为 "GameManager",并[Reset]它 创建一个 "Sphere",并将其[Scale]设置为(0.1,0 ...
- 聊聊asp.net core 授权流程
在上一篇 聊聊 asp.net core 认证和授权 中我们提到了认证和授权的基本概念,以及认证和授权的关系及他们之间的协同工作流程,在这篇文章中,我将通过分析asp.net core 3.1 授权流 ...
- Handler机制与生产者消费者模式
本文梳理了 Handler 的源码,并详细阐述了 Handler 与生产者消费者模式的关系,最后给出了多版自定义 Handler 实现.本文首发于简书,重新整理发布. 一.Handler Handle ...
- C++ 自学笔记 访问限制 Setting limits
Setting limits 让客户不能改,让设计者可以改 C++: 任何人访问 成员函数访问(同一个类的不同实例化对象可以相互访问私有成员变量) 类自己或子类访问 friend: 朋友就可以授权访问 ...
- 洛谷P2865 [USACO06NOV]Roadblocks G(次短路)
一个次短路的问题,可以套用dijkstra求最短路的方法,用dis[0][i]表示最短路:dis[1][i]表示次短路,优先队列中存有最短路和次短路,然后每次找到一条道路对他进行判断,更新最短或次短路 ...
- MySQL 窗口函数
1. 窗口函数概念和语法 窗口函数对一组查询行执行类似聚合的操作.然而,聚合操作将查询行分组到单个结果行,而窗口函数为每个查询行产生一个结果: 函数求值发生的行称为当前行 与发生函数求值的当前行相关的 ...