Django模版
一、模板
视图函数只是返回文本,而在实际生产环境中其实很少这样用,因为实际的页面大多是带有样式的HTML代码,这可以让浏览器渲染出非常漂亮的页面,目前市面上有非常多的模板系统,其中最知名最好用的是DTL和Jinja2。DTL是Django Template Language三个单词的缩写,也就是Django自带的模板语言,当然也可以配置Django支持Jinja2等其他模板引擎,但是作为Django内置的模板语言,和Django可以达到无缝衔接而不会产生一些不兼容的情况。
DTL与普通HTML文件的区别
DTL模版是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端。
二、渲染模板
渲染模板有很多种方式,以下有两种常用的方式
1、render_to_string:找到模板,然后将模版编译后渲染成Python的字符串格式,然后在通过HttpResponse类包装成一个HttpResponse对象返回回去。
2、Django提供了一个更加简便的方式,直接将模板渲染成字符串和包装成HttpResponse对象,一步到位。
1、方式一:render_to_string
新建template_intro_demo项目,并在项目中加入front app,在templates中新建一个index.html
项目结构:
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <style> body{ background - color: pink; } < / style> <body> 这个是从模板中渲染的字符串 < / body> < / html> |
template_intro_demo.urls.py
1 2 3 4 5 6 | from django.urls import path from front import views urlpatterns = [ path(" ", views.index, name=" index"), ] |
front.views.py
1 2 3 4 5 6 | from django.template.loader import render_to_string from django.http import HttpResponse def index(request): html = render_to_string( "index.html" ) return HttpResponse(html) |
运行结果如下:
2、方式二:render函数
更改front.views.py
1 2 3 4 | from django.shortcuts import render def index(request): return render(request, 'index.html' ) |
运行结果:
二、模版查找路径配置
在预目的settings.py文件中。有一个TEMPLATES配置,这个配置包含了模板引擎的配置,模板查找路径的配置,模板上下文的配置等。模板路径可以在两个地方配置。
DIRS:这是一个列表,在这个列表中可以存放所有的模板路径,以后在视图中使用render或者render_to_string澶染模板的时候,会在这个列表的路径中查找模板。
APP DIRS:默认为True,这个设置为True后,会在INSTALLEDAPPS的安装了的APP下的templates文件加中查找模板。
查找顺序:比如代码render('list.html")。先会在DIRS这个列表中依次查找路径下有没有这个模板,如果有,就返回。如果DIRS列表中所有的路径都没有找到,那么会先检查当前这个视图所处的app是否已经安装,如果已经安装了,那么就先在当前这个app下的templates文件夹中查找模板,如果没有找到,那么会在其他已经安装了的app中查找。如果所有路径下都没有找到,那么会抛出一个TemplateDoesNotExist的异常。
在settings中有模版Templates的配置,配置的路径是
1 | "DIRS" : [BASE_DIR / 'templates' ] |
BASE_DIR代表项目下面的template_intro_demo
所以模板文件需要放在项目下面的templates路径下。
新建一个test文件夹在D盘路径下
更改Templates配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | TEMPLATES = [ { "BACKEND" : "django.template.backends.django.DjangoTemplates" , "DIRS" : [f "D:\\test" ], "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" , ], }, }, ] |
此时访问http://localhost:8000/
在setting配置中还有如下配置,表示Django如果没有从DIRS目录下找到模板文件时,会从App的目录下去寻找模版文件
1 | "APP_DIRS" : True , |
将DIRS目录配置为空,并在front中新建templates文件夹,在文件夹下创建index.html
前提是app必须放在installed的app中,如果不放入installed_apps中,无法找到文件
这样再访问http://localhost:8000/
可以访问到front app中的templates中的模板文件。
三、模板变量使用详解
末班中可以包含变量,Django在渲染模板的时候,可以传递变量对应的值过去进行替换,变量的命名规范和Python非常类似,只能是阿拉伯数字和英文字符以及下划线的组合,不能出现标点符号等特殊字符,变量需要通过视图函数渲染,视图函数在使用render或者render_to_string的时候可以传递一个context的参数,这个参数是一个字典类型,以后在模板中的变量就从这个字典中读取值的。
1、在模板中使用变量,需要将变量放到‘{{变量}}’中
2、如果想要访问对象的属性,那么可以通过‘对象.属性名’来进行访问
3、如果想要访问一个字典的key对应的value,那么只能通过‘字典.key’的方式进行访问,不能通过'中括号[]'的形式进行访问。
4、因为在访问字典的'key'时候也是使用'点.'来访问,否则字典的那个属性将变成字典中的key了。
5、如果想要访问列表或者元组,那么也是通过'点.'的方式进行访问,不能通过'中括号[]'的形式进行访问。
访问变量
新建项目template_variable_demo
urls.py
1 2 3 4 5 6 | from django.urls import path from . import views urlpatterns = [ path("", views.index), ] |
views.py
1 2 3 4 5 6 7 | from django.shortcuts import render def index(request): context = { 'username' : 'zhiliao' } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 11 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> 首页 <p>{{ username }}< / p> < / body> < / html> |
运行后结果:
传递对象
views.py,传递对象Person
1 2 3 4 5 6 7 8 9 10 11 | from django.shortcuts import render class Person( object ): def __init__( self , username): self .username = username def index(request): p = Person( "zhiliao" ) context = { 'person' :p } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ person.username }} < / body> < / html> |
运行后结果为:
传递对象属性
views.py
1 2 3 4 5 6 7 8 9 10 11 12 | from django.shortcuts import render class Person( object ): def __init__( self , username): self .username = username def index(request): context = { 'person' :{ 'username' : "zhiliao" } } return render(request, 'index.html' ,context = context) |
更改index.html,访问username
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ person.username }} < / body> < / html> |
运行结果为:
获取属性关键字
views.py
1 2 3 4 5 6 7 8 9 10 11 12 | from django.shortcuts import render class Person( object ): def __init__( self , username): self .username = username def index(request): context = { 'person' :{ 'username' : "zhiliao" } } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ person.keys }} < / body> < / html> |
运行结果如下:
如果字典中有关键字keys,则直接访问keys值
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 | from django.shortcuts import render class Person( object ): def __init__( self , username): self .username = username def index(request): context = { 'person' :{ 'name' : "zk" , 'keys' : "帅气" } } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ person.keys }} < / body> < / html> |
运行结果:
获取列表中的值
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from django.shortcuts import render class Person( object ): def __init__( self , username): self .username = username def index(request): context = { 'person' :[ '程咬金' , '鲁班一号' , '阿娇' ] } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ person. 0 }} < / body> < / html> |
运行结果:
获取元组中的值
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from django.shortcuts import render class Person( object ): def __init__( self , username): self .username = username def index(request): context = { 'person' :( '程咬金' , '鲁班一号' , '阿娇' ) } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ person. 0 }} < / body> < / html> |
运行结果:
模板中的常用标签
if标签
1、if标签相当于python中的if语句,有elif和else相对应,但是所有的标签都需要用标签符号({%%})进行包裹。if标签中可以使用==、!=、<=、>、>=、in、not in、is、is not等判断运算符。
1、所有的标签都是在‘{%%}’之间
2、if标签有闭合标签,就是{% endif %}
3、if标签的判断运算符,就跟python中的判断运算符是一样的,'==、!=、<=、>、>=、in、not in、is、is not'这些都可以使用
4、还可以使用'elif'以及'else'标签
新建项目template_if_demo
urls.py
1 2 3 4 5 6 | from django.urls import path from template_if_demo import views urlpatterns = [ path(" ", views.index, name=" index"), ] |
views.py
1 2 3 4 5 6 7 | from django.shortcuts import render def index(request): context = { 'age' : 17 } return render(request, "index.html" ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> { % if age < 18 % } <p>您是未成年人,不能进入网吧< / p> { % elif age = = 18 % } <p>您是成年人,能进入网吧< / p> { % else % } <p>您年级太大了,不能进入网吧< / p> { % endif % } < / body> < / html> |
运行结果:
更改views.py
1 2 3 4 5 6 7 8 9 10 11 | from django.shortcuts import render def index(request): context = { 'heros' :[ '鲁班一号' , '项羽' , '程咬金' ] } return render(request, "index.html" ,context = context) |
更改index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> { % if '鲁班一号' in heros % } <p>鲁班一号正在待命< / p> { % else % } <p>鲁班一号正在睡觉< / p> { % endif % } < / body> < / html> |
运行结果:
for...in...标签
for...in...标签:for...in...类似于Python中的for...in...,可以遍历列表、元组、字符串、字典等一切可以遍历的对象。
新建项目template_for_demo,新建urls.py和index.html
正序遍历
urls.py
1 2 3 4 5 6 | from django.urls import path from template_for_demo import views urlpatterns = [ path("", views.index), ] |
views.py
1 2 3 4 5 6 7 8 9 10 11 12 | from django.shortcuts import render def index(request): context = { 'books' :[ '三国演义' , '红楼梦' , '西游记' , '水浒传' ] } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <ul> { % for book in books % } <li>{{ book }}< / li> { % endfor % } < / ul> < / body> < / html> |
运行结果:
反序遍历
更改index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <ul> { % for book in books reversed % } <li>{{ book }}< / li> { % endfor % } < / ul> < / body> < / html> |
运行结果如下:
遍历字典的时候,需要使用items、keys和value等方法,在DTL中,执行一个方法不能使用圆括号的形式。
更改views.py
1 2 3 4 5 6 7 8 9 10 11 | from django.shortcuts import render def index(request): context = { 'person' :{ 'username' : 'zhiliao' , 'age' : 23 , 'height' : 100 , } } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <ul> { % for key in person.keys % } <li>{{ key }}< / li> { % endfor % } < / ul> <ul> { % for value in person.values % } <li>{{ value }}< / li> { % endfor % } < / ul> <ul> { % for key,value in person.items % } <li>{{ key }} / {{ value }}< / li> { % endfor % } < / ul> < / body> < / html> |
运行结果:
在for循环中,DTL提供了一些变量可供使用,这些变量如下:
1、forloop.counter:当前循环的下标,以1作为起始值
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | from django.shortcuts import render def index(request): context = { 'books' :[ { 'name' : '三国演义' , 'author' : '罗贯中' , 'price' : 199 }, { 'name' : '水浒传' , 'author' : '施耐庵' , 'price' : 200 }, { 'name' : '西游记' , 'author' : '吴承恩' , 'price' : 201 }, { 'name' : '红楼梦' , 'author' : '曹雪芹' , 'price' : 202 }, ] } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <table> <thead> <tr> <td>序号< / td> <td>书名< / td> <td>作者< / td> <td>价格< / td> < / tr> < / thead> <tbody> { % for book in books % } <tr> <td>{{ forloop.counter }}< / td> <td>{{ book.name }}< / td> <td>{{ book.author }}< / td> <td>{{ book.price }}< / td> < / tr> { % endfor % } < / tbody> < / table> < / body> < / html> |
运行结果如下:
2、forloop.counter0:当前循环的下标,以0作为起始值
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <table> <thead> <tr> <td>序号< / td> <td>书名< / td> <td>作者< / td> <td>价格< / td> < / tr> < / thead> <tbody> { % for book in books % } <tr> <td>{{ forloop.counter0 }}< / td> <td>{{ book.name }}< / td> <td>{{ book.author }}< / td> <td>{{ book.price }}< / td> < / tr> { % endfor % } < / tbody> < / table> < / body> < / html> |
输出结果:
3、forloop.recounter:当前循环的反向下标值,比如列表中有5个元素,那么第一次遍历这个属性是等于5,第二次是4,以此类推。并且是以1作为最后一个元素的下标。
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <table> <thead> <tr> <td>序号< / td> <td>书名< / td> <td>作者< / td> <td>价格< / td> < / tr> < / thead> <tbody> { % for book in books % } <tr> <td>{{ forloop.revcounter }}< / td> <td>{{ book.name }}< / td> <td>{{ book.author }}< / td> <td>{{ book.price }}< / td> < / tr> { % endfor % } < / tbody> < / table> < / body> < / html> |
输出结果:
4、forloop.recounter0:类似于forloop recounter,不同的是最后一个元素的下标是从0开始的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <table> <thead> <tr> <td>序号< / td> <td>书名< / td> <td>作者< / td> <td>价格< / td> < / tr> < / thead> <tbody> { % for book in books % } <tr> <td>{{ forloop.revcounter0 }}< / td> <td>{{ book.name }}< / td> <td>{{ book.author }}< / td> <td>{{ book.price }}< / td> < / tr> { % endfor % } < / tbody> < / table> < / body> < / html> |
输出结果:
5、forloop.first:是否是第一次遍历
6、forloop.last:是否是最后一次遍历
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <table> <thead> <tr> <td>序号< / td> <td>书名< / td> <td>作者< / td> <td>价格< / td> < / tr> < / thead> <tbody> { % for book in books % } <tr> { % if forloop.first % } <tr style = "background-color: red;" > { % elif forloop.last % } <tr style = "background-color: pink;" > { % else % } <tr> { % endif % } <td>{{ forloop.revcounter0 }}< / td> <td>{{ book.name }}< / td> <td>{{ book.author }}< / td> <td>{{ book.price }}< / td> < / tr> { % endfor % } < / tbody> < / table> < / body> < / html> |
输出结果:
7、forloop.parentloop:如果有多个循环嵌套,那么这个属性代表的是上一级的for循环
8、for...in...empty标签:这个标签和for...in...是一样的,只不过是在遍历的对象中如果没有元素的情况下,会执行empty中的内容。
views.py
1 2 3 4 5 6 7 | from django.shortcuts import render def index(request): context = { 'comments' :[] } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> <ul> { % for comment in comments % } <li>{{ comment }}< / li> { % empty % } <li>没有任何评论< / li> { % endfor % } < / ul> < / body> < / html> |
运行结果:
模版中的for...in...没有continue和break语句,这一点和Python中有很大的不同。
with标签
with标签:在模版中定义变量,有时候一个变量访问的时候比较复杂,那么可以先把这个复杂的变量缓存在一个变量上,以后直接使用这个变量就可以了。
1、在模版中,想要定义变量,可以使用with语句来实现
2、with语句有两种使用方式,一种是"with xxxx"的形式,第二种是"with xxx as xxx"的形式。
3、定义的变量只能在with语句中使用,在with语句块外面使用取不到这个变量。
新建一个工程template_with_demo
urls.py
1 2 3 4 5 6 | from django.urls import path from . import views urlpatterns = [ path( "" , views.index), ] |
views.py
1 2 3 4 5 6 7 8 9 10 11 | from django.shortcuts import render def index(request): context = { 'persons' :[ '张三' , '李四' , '王五' ] } return render(request, 'index.html' ,context = context) |
with用法一:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> { % with zhangsan = persons. 0 % } <p>{{ zhangsan }}< / p> <p>{{ zhangsan }}< / p> { % endwith % } < / body> < / html> |
运行结果:
with用法二:
1 2 3 4 5 6 7 8 9 10 11 12 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> { % with persons. 0 as zs % } <p>{{ zs }}< / p> { % endwith % } < / body> < / html> |
运行结果:
Url标签
url标签:在模版中,我们经常要写一些url,比如某个‘a’标签中需要定义'href'属性,当然如果通过编码的方式直接将这个'url'写死在里面也是可以。但是这样对于以后项目的维护可能不是一件好事,因此建议使用这种反转的方式来实现,类似于django中的reverse一样。示例代码如下:
新建项目template_url_demo
urls.py
1 2 3 4 5 6 7 8 9 10 11 | from django.urls import path from . import views urlpatterns = [ path(" ", views.index,name=" index"), path( "book/" , views.books,name = "books" ), path( "book/detail/<book_id>/<category>" , views.books_detail,name = "books_detail" ), path( "movie/" , views.movies,name = "movies" ), path( "city/" , views.city,name = "city" ), path( "login/" ,views.login,name = "login" ), ] |
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | from django.http import HttpResponse from django.shortcuts import render def index(request): return render(request, 'index.html' ) def login(request): next = request.GET.get( 'next' ) text = "登录页面,登陆完成后要跳转的url是 %s" % next return HttpResponse(text) def books(request): return HttpResponse( "读书页面" ) def books_detail(request,book_id,category): res = "您的书籍id是%s 书籍分类是%s" % (book_id,category) return HttpResponse(res) def movies(request): return HttpResponse( "电影页面" ) def city(request): return HttpResponse( "城市页面" ) |
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> <style> .nav{ overflow: hidden; } .nav li{ float : left; list - style: none; margin: 0 0 20px 20px ; } < / style> < / head> <body> <ul class = "nav" > <li><a href = "/" >首页< / a>< / li> <li><a href = "{% url 'books' %}" >读书< / a>< / li> <li><a href = "{% url 'movies' %}" >电影< / a>< / li> <li><a href = "{% url 'city' %}" >同城< / a>< / li> <li><a href = "{% url 'books_detail' book_id='1' category=1 %}" >最火的一篇文章< / a>< / li> <li><a href = "{% url 'login' %}?next=/" >登录< / a>< / li> < / ul> < / body> < / html> |
运行结果:
Spaceless标签
Spaceless标签:移除html标签中的空白字符,包括空格、tab键、换行等。示例代码如下:
1 2 3 4 5 | { % spaceless % } <p> <a href = "{% url 'books' %}" >读书< / a> < / p> { % endspaceless % } |
可以看到移除空白字符之后的代码如下:
autoescape标签
1、DTL中默认开启了自动转义,会将哪些特殊字符进行转义,比如会将'<'转移成'<'等。
2、使用DTL的自动转义,可以使网站不容易出现XSS漏洞。
3、如果变量确实是可信任的,那么可以使用'autoescape'标签来关掉自动转义。
新建一个项目工程template_autoescape_demo项目
urls.py
1 2 3 4 5 6 | from django.urls import path from template_autoescape_demo import views urlpatterns = [ path(" ", views.index, name=" index"), ] |
views.py
1 2 3 4 5 6 7 | from django.shortcuts import render def index(request): context = { 'info' : "<a href='www.baidu.com'>百度</a>" } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 11 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ info }} <a href = 'https://www.baidu.com' >百度< / a> < / body> < / html> |
运行结果如下:
查看网页源代码可以看到网页中的html源码是经过转义的
现在关闭自动转义源代码,更改index.html文件
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> { % autoescape off % } {{ info }} { % endautoescape % } <a href = 'https://www.baidu.com' >百度< / a> < / body> < / html> |
运行结果如下:
关闭自动转义以后,模版文件html会自动渲染
verbatim标签
默认在DTL模板中是会去解析那些特殊字符的。比如{%和%}以及{{等。如果你在某个代码片段中不想使用DTL的解析引擎。那么你可以把这个代码片段放在verbatim标签中。示例代码如下:
新建项目template_verbatim_demo
urls.py
1 2 3 4 5 6 7 | from django.urls import path from template_verbatim_demo import views urlpatterns = [ path("", views.index), ] |
views.py
1 2 3 4 5 6 7 | from django.shortcuts import render def index(request): context = { 'hello' : "hello" } return render(request, 'index.html' ,context = context) |
index.html
1 2 3 4 5 6 7 8 9 10 11 12 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> { % verbatim % } {{ hello }} { % endverbatim % } < / body> < / html> |
运行结果如下:
可以看到模版文件中没有解析context参数中的hello字段
其他模版标签可以查看网址https://docs.djangoproject.com/en/2.0/ref/templates/builtins/
模板常用的过滤器
在模版中,有时候需要对一些数据进行处理以后才能使用,一般在Python中我们是通过函数的形式来完成的。而在模板中,则是通过过滤器来实现的。过滤器使用的是"|"来使用。
因为在DTL中,不支持函数的调用形式"()",因此不能给函数传递参数,这将有很大的局限性,而过滤器其实就是一个函数,可以对需要处理的参数进行处理,并且还可以额外接收一个参数(也就是说,最多只能有两个参数)
新建一个项目template_filter_demo
add过滤器
将传进来的参数添加到原来的值上面,这个过滤器会尝试将"值"和"参数"转换成整型然后进行相加,如果转换成整型过程中失败了,那么会将"值"和"参数"进行拼接。如果是字符串,那么会拼接成字符串,如果是列表,那么会拼接成一个列表。
数字拼接
urls.py
1 2 3 4 5 6 7 | from django.urls import path from template_filter_demo import views urlpatterns = [ path(" ",views.index,name=" index"), path( "add/" ,views.add_view,name = "index" ), ] |
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 | from django.shortcuts import render def greet(word): return 'Hello World! %s' % word def index(request): context = { 'greet' : 2 } return render(request, 'index.html' ,context = context) def add_view(request): return render(request, 'add.html' ) |
add.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>add过滤器< / title> < / head> <body> {{ "1" | add: "2" }} < / body> < / html> |
index.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ greet | add: "2" }} < / body> < / html> |
访问index.html
访问add.html
字符串拼接
更改index.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ greet | add: "2ssss" }} < / body> < / html> |
更改views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 | from django.shortcuts import render def greet(word): return 'Hello World! %s' % word def index(request): context = { 'greet' : '2' } return render(request, 'index.html' ,context = context) def add_view(request): return render(request, 'add.html' ) |
输出结果如下:
列表拼接
views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | from django.shortcuts import render def greet(word): return 'Hello World! %s' % word def index(request): context = { 'greet' : '2' } return render(request, 'index.html' ,context = context) def add_view(request): context = { 'value1' :[ '1' , '2' , '3' ], 'value2' :[ '4' , '5' , '6' ], } return render(request, 'add.html' ,context = context) |
add.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>add过滤器< / title> < / head> <body> {{ value1 | add:value2 }} < / body> < / html> |
输出结果:
cut过滤器
移除值中所有指定的字符串。
views.py
1 2 3 4 | from django.shortcuts import render def cut_view(request): return render(request, 'cut.html' ) |
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "cut/" ,views.cut_view,name = "cut" ), ] |
cut.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ "h e l l o" |cut: " " }} < / body> < / html> |
运行结果如下:
date过滤器
讲一个日期按照指定的格式,格式化成字符串,示例代码如下:
date格式化输出方式
格式字符 | 描述 | 示例 |
Y | 四位数字的年份 | 2018 |
m | 两位数字的月份 | 01-12 |
n | 月份,1-9没有前面的0格式 | 1-12 |
d | 两位数字的天 | 01-31 |
j | 天,但是1-9前面没有0前缀 | 1-31 |
g | 小时,12小时格式的,1-9前面没有0的前缀 | 1-12 |
h | 小时,12小时格式的,1-9前面有0的前缀 | 01-12 |
G | 小时,24小时格式的,1-9前面没有0的前缀 | 1-23 |
H | 小时,24小时格式的,1-9前面有0的前缀 | 01-23 |
i | 分钟,1-9前面有0的前缀 | 01-59 |
s | 秒,1-9前面有0的前缀 | 00-59 |
修改views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def date_view(request): context = { 'today' :datetime.now() } return render(request, 'date.html' ,context = context) |
修改urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "date/" ,views.date_view,name = "date" ), ] |
新建date.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>date< / title> < / head> <body> {{ today|date: "Y/m/d H:i:s" }} < / body> < / html> |
运行结果如下:
default过滤器
如果值被评估为False,比如[],"",None,{}等这些在if判断中为False的值,都会使用default过滤器提供的默认值。
示例代码如下:
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "default/" ,views.default_view,name = "default" ), ] |
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def default_view(request): context = { 'value' :'', } return render(request, "default.html" ,context = context) |
default.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>default< / title> < / head> <body> {{ value|default: "我是默认值" }} < / body> < / html> |
当value值为空值时,会用default缺省值替代
运行结果如下:
更改views.py
1 2 3 4 5 6 7 8 9 | from datetime import datetime from django.shortcuts import render def default_view(request): context = { 'value' : '不使用缺省值' , } return render(request, "default.html" ,context = context) |
运行结果如下:
如果为空列表
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def default_view(request): context = { 'value' :[], } return render(request, "default.html" ,context = context) |
也会使用缺省值
如果使用空字典
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def default_view(request): context = { 'value' : {}, } return render(request, "default.html" ,context = context) |
运行结果如下:
如果是None值
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def default_view(request): context = { 'value' : None , } return render(request, "default.html" ,context = context) |
运行结果如下:
default_if_none过滤器
如果值是None,那么将会使用default_if_none提供的默认值,这个和default有区别,default是所有被评估为False的都会使用默认值,而default_if_none则只有这个值是等于None的时候才会使用默认值。
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def default_view(request): context = { 'value' : None , } return render(request, "default.html" ,context = context) |
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "default/" ,views.default_view,name = "default" ), ] |
default.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>default< / title> < / head> <body> {{ value|default_if_none: "我是默认值" }} < / body> < / html> |
运行结果如下:
更改views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def default_view(request): context = { 'value' : '', } return render(request, "default.html" ,context = context) |
运行结果如下:
因为值为空不为None,不使用缺省值
更改views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def default_view(request): context = { 'value' : {}, } return render(request, "default.html" ,context = context) |
运行结果如下:
first过滤器
返回列表/元组/字符串中的第一个元素。
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def first_view(request): context = { 'value' : [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ], } return render(request, "first.html" ,context = context) |
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "first/" ,views.first_view,name = "first" ), ] |
first.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>first< / title> < / head> <body> {{ value|first }} < / body> < / html> |
运行结果如下:
last过滤器
返回列表/元组/字符串中的最后一个元素。
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def last_view(request): context = { 'value' : [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ], } return render(request, "last.html" ,context = context) |
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "last/" ,views.last_view,name = "last" ), ] |
last.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>last< / title> < / head> <body> {{ value|last }} < / body> < / html> |
运行结果如下:
floatformat过滤器
使用四舍五入的方式格式化一个浮点类型,如果这个过滤器没有传递任何参数。那么只会在小数点后保留一个小时,如果小数点后面全是0,那么只会保留整数。当然也可以传递一个参数,标识具体要保留几个小数
1、如果没有传递参数
value | 模板代码 | 输出 |
32.23234 | {{ value|floatformat }} | 32.2 |
34.000 | {{ value|floatformat }} | 34 |
34.260 | {{ value|floatformat }} | 34.3 |
示例代码如下:
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def floatformat_view(request): context = { 'value' : 32.23234 } return render(request, "floatformat.html" ,context = context) |
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "floatformat/" ,views.floatformat_view,name = "floatformat" ), ] |
floatformat.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>floatformat< / title> < / head> <body> {{ value|floatformat }} < / body> < / html> |
输出结果如下:
更改值
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def floatformat_view(request): context = { 'value' : 34.000 } return render(request, "floatformat.html" ,context = context) |
更改值
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def floatformat_view(request): context = { 'value' : 34.260 } return render(request, "floatformat.html" ,context = context) |
2、如果传递参数:
value | 模板代码 | 输出 |
34.23234 | {{ value|floatformat:3 }} | 34.232 |
34.00000 | {{ value|floatformat:3}} | 34.000 |
34.26000 | {{ value|floatformat:3 }} | 34.260 |
示例代码如下:
更改floatformat.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>floatformat< / title> < / head> <body> {{ value|floatformat: 3 }} < / body> < / html> |
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def floatformat_view(request): context = { 'value' : 34.260 } return render(request, "floatformat.html" ,context = context) |
运行结果如下:
Join过滤器
类似于Python中的join,将列表/字符串用指定的字符进行拼接。
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def join_view(request): context = { 'value' :[ 1 , 2 , 3 ] } return render(request, "join.html" ,context = context) |
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "join/" ,views.join_view,name = "join" ), ] |
join.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> < / head> <body> {{ value|join: "/" }} < / body> < / html> |
运行结果如下:
length过滤器
获取一个列表/元组/字符串的长度
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def length_view(request): context = { 'value' :[ 1 , 2 , 3 , 5 , 6 , 7 , 8 ] } return render(request, "length.html" ,context = context) |
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "length/" ,views.length_view,name = "length" ), ] |
length.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>length< / title> < / head> <body> {{ value|length }} < / body> < / html> |
运行结果如下:
lower过滤器
将值中所有的字符转换为小写,示例代码如下:
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def lower_view(request): context = { 'value' : "SDFADADA" } return render(request, "lower.html" ,context = context) |
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "lower/" ,views.lower_view,name = "lower" ), ] |
lower.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>lower< / title> < / head> <body> {{ value|lower }} < / body> < / html> |
运行结果如下:
upper过滤器
将值中所有的字符转换为大写,示例代码如下:
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "upper/" ,views.upper_view,name = "upper" ), ] |
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def upper_view(request): context = { 'value' : "sasasasad" } return render(request, "upper.html" ,context = context) |
upper.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>upper< / title> < / head> <body> {{ value|upper }} < / body> < / html> |
运行结果如下:
random过滤器
随机的在列表/字符串/元组中选择一个值
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "random/" ,views.random_view,name = "random" ), ] |
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def random_view(request): context = { 'value' :( 1 , 2 , 3 , 4 , 5 , 6 ) } return render(request, "random.html" ,context = context) |
random.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>random< / title> < / head> <body> {{ value|random }} < / body> < / html> |
运行结果如下:
safe过滤器
标记一个字符串是安全的,也就是关闭这个字符串的自动转义。
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "safe/" ,views.safe_view,name = "safe" ), ] |
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def safe_view(request): context = { 'value' : "<script>alert('hello');</script>" } return render(request, "safe.html" ,context = context) |
safe.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>safe< / title> < / head> <body> {{ value|safe }} < / body> < / html> |
输出结果如下:
查看源代码
相当于字符串转变为js代码
slice过滤器
类似于Python中的切片操作。示例代码如下:
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "slice/" ,views.slice_view,name = "slice" ), ] |
views.py
1 2 3 4 5 6 7 | from django.shortcuts import render def slice_view(request): context = { 'value' :[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] } return render(request, "slice.html" ,context = context) |
slice.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title> slice < / title> < / head> <body> {{ value| slice : "2:" }} < / body> < / html> |
运行结果如下:
取2后面的值
设置步长
slice.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title> slice < / title> < / head> <body> {{ value| slice : "1::2" }} < / body> < / html> |
运行结果如下:
stringtags标签
删除字符串中所有的html标签。示例代码如下
urls.py
1 2 3 4 5 6 | from django.urls import path from template_filter_demo import views urlpatterns = [ path( "stringtags/" ,views.stringtags_view,name = "string_tags" ), ] |
views.py
1 2 3 4 5 6 7 8 | from datetime import datetime from django.shortcuts import render def stringtags_view(request): context = { 'value' : '<script>alert("hello");</script>' } return render(request, "stringtags.html" ,context = context) |
stringtags.html
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Stringtags< / title> < / head> <body> {{ value|striptags }} < / body> < / html> |
运行结果如下:
删除了<scripts>标签
truncatechars标签
如果指定的字符串长度超过了过滤器指定的长度,那么就会进行切割,并且会拼接三个点来作为省略号。示例代码如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)