引言
你可能已经注意到我们在例子视图中返回文本的方式有点特别。 也就是说,HTML被直接硬编码在 Python代码之中。
def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意。 让我们来看一下为什么:
- 
对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。 
- 
Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。 
- 
程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。 
基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式,这就是本章要具体讨论的问题。
一:模板的介绍
1:什么是模板
只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板。
官方文档的定义:
模板就是一个简单的文本文件,它可以生成任何文本格式(HTML,XML,CSV等)。
模板中包含变量和标签,当模板被执行时,变量会被赋值,而标签是控制模板的逻辑的。
2:模板语法的分类
(1)变量:{{}} {{ 变量名 }}
(2)标签:{% %} {% tag %}.
3:模板语法的渲染方式
模板语法由render()渲染的.
浏览器接收到的数据是已经经过渲染之后的数据
二:模板语法的介绍
1:变量介绍
变量看起来像这样:{{ 变量名 }},当模板引擎遇到变量时,会计算这个变量,并把结果赋值给它。变量名是由任何的数字,字母以及下划线组成。点(“.”)也会出现在变量部分,当然他有特殊用途,稍后会说明。特别注意的是,变量名中不能出现空格符以及任何的标点符号。
上面说到点也会出现在变量部分,它的作用就是用来访问变量的属性的。
2:变量(渲染变量)
(1) 变量渲染各种类型
 
1 <body> 2 <p>变量渲染各种数据类型</p> 3 <ul> 4 <li>name:{{ name }}</li> 5 <li>age:{{ age }}</li> 6 <li>student{{ student }}</li> 7 </ul> 8 </body>
 
1 def index(request): 2 name = 'lilz' #str 3 age = 20 #int 4 student=['egon','wusir','yaoshen'] #list 5 return render(request,'index.html',{'name':name,'age':age,'student':student})
测试:

(2)深度查询
使用句点符(.)一层一层往里层查询
还是上面的案例:文件不做修改,只更改index.html中的
<li>student:{{ student.0 }}</li>
那么测试结果

(3)locals
那么如果需要传的非常多的参数时,locals代替传变量的参数
name = 'lilz' #str age = 20 #int student=['egon','wusir','yaoshen'] #list return render(request,'index.html',{'name':name,'age':age,'student':student}) return render(request,'index.html',locals()) #效果和上面的相同
(4)filter过滤器--内置
作用:
过滤器转换变量和标记参数的值。简言之,把本来的数据在根据规则过滤一遍。
语法:
{{var|filter_name:参数}} ---{{变量|过滤器名:参数}}
请参考博客:Django-模板语法-过滤器
3:标签(渲染标签)
标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %})
请参考博文:Django-模板语法-标签
三:模板继承
1:引言

2:介绍
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。
3:案例
我们下面的计划是做一个母版,让其他子模板页面能够继承母版
(1)母版文件
 
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> 7 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" 8 integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> 9 <style> 10 * { 11 padding: 0; 12 margin: 0; 13 } 14 15 .header { 16 width: 100%; 17 height: 50px; 18 background-color: #369; 19 } 20 </style> 21 </head> 22 <body> 23 <div class="header"></div> 24 <div class="container"> 25 <div class="row"> 26 <div class="col-md-3"> 27 <div class="panel panel-success"> 28 <div class="panel-body"> 29 30 </div> 31 <div class="panel-footer"> 32 <p><a href="/app01/order/">订单</a></p> 33 <p><a href="">商品信息</a></p> 34 <p><a href="">价格</a></p> 35 <p><a href="">走势</a></p> 36 </div> 37 </div> 38 </div> 39 <div class="col-md-9"> 40 41 <div class=""> 42 {% block content %} 43 <h3>welcome !</h3> 44 {% endblock %} 45 </div> 46 </div> 47 48 </div> 49 </div> 50 </body> 51 </html>
(2)子模板文件
 
1 {% extends 'base.html' %} 2 3 {% block content %} 4 <div class="jumbotron"> 5 <h1>Hello, world!</h1> 6 <p>...</p> 7 <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p> 8 </div> 9 {% endblock %}
 
1 {% extends 'base.html' %} 2 3 {% block content %} 4 <h3>这是订单</h3> 5 {% endblock %}
(3)py文件
 
1 from django.contrib import admin 2 from django.urls import path,re_path,include 3 from app01 import views 4 5 6 urlpatterns = [ 7 8 re_path(r'index/$',views.index), 9 re_path(r'order/$',views.order), 10 ]
 
1 from django.shortcuts import render,HttpResponse 2 3 def index(request): 4 5 return render(request,'index.html') 6 7 def order(request): 8 9 return render(request,'order.html')
测试
然后我们点击订单,就会跳到下面页面
总结
extends 标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先,它将定位父模版——在此例中,就是“base.html”。
那时,模版引擎将注意到 base.html 中的 block 标签,并用子模版中的内容来替换这些block。
注意:
- 
如果你在模版中使用 {% extends %}标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。
- 
在base模版中设置越多的 {% block %}标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子(block)总比少一点好。
- 
如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% block %}中。
- 
If you need to get the content of the block from the parent template, the {{ block.super }}variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using{{ block.super }}will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.- 在母版中的一个block里面的内容,当子模板继承的时候就会覆盖母版的这个block里面的内容。那么我们既想要这个内容还想要子母版的内容,该怎么办呢?
- 方法就是在子模板继承的时候添加一个{{ block.super }}
 
- 
为了更好的可读性,你也可以给你的 {% endblock %}标签一个 名字 。例如:123{%block content%}...{%endblock content%}在大型模版中,这个方法帮你清楚的看到哪一个 {% block %}标签被关闭了。
- 不能在一个模版中定义多个相同名字的 block标签。
4:模板继承的补充--include
母版继承一个子模板文件
(1)母版
<body> <h3>编辑书籍</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> {% include 'form.html' %} </div> </div> </div> </body>
(2)子模板form.html(全部数据)(不做任何处理)
<form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div class="form-group"> <label for="title">{{ field.label }}</label> {{ field }} <span>{{ field.errors.0 }}</span> </div> {% endfor %} <input type="submit" value="提交" class="btn btn-default pull-right"> </form>
这样的效果就是母版把子模板数据加入到自己相应的位置
5:模板继承的补充--include--优化-inclusion_tag
5.1缺点
我们先说下上面的子模板的缺点:
子模板中的数据有视图提供,但是这是有问题的,如果同时有其他文件继承母版,那么如果对应的视图函数就必须得提供数据才行。这样太麻烦,数据和模板脱离开了。
{% include 'form.html' %}  #这个include是简单地,只需要把form.html文件中的内容拿过来放到该位置就行了
5.2解决数据和模板脱离的方法--自定义标签
步骤和自定义过滤器一样:博客
5.2.1 自定义标签文件--提供数据
from django.template import Library register = Library() @register.inclusion_tag("includ.html") def get_menu_style(): menu_list=[123,666,999] return {"menu_list":menu_list}
 
5.2.2子模板文件--加工数据与模板语法的中转站
includ.html
<ul> {% for foo in menu_list %} <li>{{ foo }}</li> {% endfor %} </ul>
5.2.3母版文件---调用
layout.html
                {% load myfilters_tags %}  #加载标签文件
                {% get_menu_style %}  #模板语法
四:render方法的作用
其实我们写的模板语法与浏览器一点关系都没有。这其实都是后端解析数据,就是在render这个地方。其实render会把对应的模板文件读出来。全部看成字符串。在字符串里找到模板语法,把视图函数中数据替换到相应位置。然后替换为前端代码
参考博文:Yuan 先生
 
 


 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号