官方文档css
你可能已经注意到咱们在例子视图中返回文本的方式有点特别。 也就是说,HTML被直接硬编码在 Python代码之中。html
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
Python 代码编写和 HTML 设计是两项不一样的工做,大多数专业的网站开发环境都将他们分配给不一样的人员(甚至不一样部门)来完成。 设计者和HTML/CSS的编码人员不该该被要求去编辑Python的代码来完成他们的工做。程序员
程序员编写 Python代码和设计人员制做模板两项工做同时进行的效率是最高的,远胜于让一我的等待另外一我的完成对某个既包含 Python又包含 HTML 的文件的编辑工做。npm
基于这些缘由,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 咱们可使用 Django的 模板系统 (Template System)来实现这种模式,这就是本章要具体讨论的问题。django
只要是在html里面有模板语法就不是html文件了,这样的文件就叫作模板。bootstrap
官方文档的定义:后端
模板就是一个简单的文本文件,它能够生成任何文本格式(HTML,XML,CSV等)。浏览器
模板中包含变量和标签,当模板被执行时,变量会被赋值,而标签是控制模板的逻辑的。
(1)变量:{{}} {{ 变量名 }}
(2)标签:{% %} {% tag %}.
模板语法由render()渲染的.
浏览器接收到的数据是已经通过渲染以后的数据
变量看起来像这样:{{ 变量名 }}
,当模板引擎遇到变量时,会计算这个变量,并把结果赋值给它。变量名是由任何的数字,字母以及下划线组成。点(“.”)也会出如今变量部分,固然他有特殊用途,稍后会说明。特别注意的是,变量名中不能出现空格符以及任何的标点符号。
上面说到点也会出如今变量部分,它的做用就是用来访问变量的属性的。
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})
测试:
使用句点符(.)一层一层往里层查询
仍是上面的案例:文件不作修改,只更改index.html中的
<li>student:{{ student.0 }}</li>
那么测试结果
那么若是须要传的很是多的参数时,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()) #效果和上面的相同
做用:
过滤器转换变量和标记参数的值。简言之,把原本的数据在根据规则过滤一遍。
语法:
{{var|filter_name:参数}} ---{{变量|过滤器名:参数}}
请参考博客:Django-模板语法-过滤器
标签看起来像是这样的: {% tag %}
。标签比变量更加复杂:一些在输出中建立文本,一些经过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签须要开始和结束标签 (例如{% tag %} ...
标签 内容 ... {% endtag %})
请参考博文:Django-模板语法-标签
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可让您建立一个基本的“骨架”模版,它包含您站点中的所有元素,而且能够定义可以被子模版覆盖的 blocks 。
咱们下面的计划是作一个母版,让其余子模板页面可以继承母版
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>
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 %}
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.
为了更好的可读性,你也能够给你的 {% endblock %}
标签一个 名字 。例如:
1
2
3
|
{
%
block content
%
}
...
{
%
endblock content
%
}
|
在大型模版中,这个方法帮你清楚的看到哪个 {% block %}
标签被关闭了。
block
标签。
母版继承一个子模板文件
(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>
这样的效果就是母版把子模板数据加入到本身相应的位置
咱们先说下上面的子模板的缺点:
子模板中的数据有视图提供,可是这是有问题的,若是同时有其余文件继承母版,那么若是对应的视图函数就必须得提供数据才行。这样太麻烦,数据和模板脱离开了。
{% include 'form.html' %} #这个include是简单地,只须要把form.html文件中的内容拿过来放到该位置就好了
步骤和自定义过滤器同样:博客
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}
includ.html
<ul> {% for foo in menu_list %} <li>{{ foo }}</li> {% endfor %} </ul>
layout.html
{% load myfilters_tags %} #加载标签文件 {% get_menu_style %} #模板语法
其实咱们写的模板语法与浏览器一点关系都没有。这其实都是后端解析数据,就是在render这个地方。其实render会把对应的模板文件读出来。所有当作字符串。在字符串里找到模板语法,把视图函数中数据替换到相应位置。而后替换为前端代码
参考博文:Yuan 先生