Django-模板语法

官方文档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

 一:模板的介绍

1:什么是模板

只要是在html里面有模板语法就不是html文件了,这样的文件就叫作模板。bootstrap

官方文档的定义:后端

模板就是一个简单的文本文件,它能够生成任何文本格式(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>
index.html
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})
views.py

测试:

 

(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>
base.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 %}
index.html
1 {% extends 'base.html' %}
2 
3 {% block content %}
4     <h3>这是订单</h3>
5 {% endblock %}
order.html

 

 (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 ]
app01/urls.py
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')
views.py

 

测试

而后咱们点击订单,就会跳到下面页面

 

总结

 

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 %} 标签一个 名字 。例如:

    1
    2
    3
    { %  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 先生

相关文章
相关标签/搜索