# 第七節:模版結構優化
# 模版結構優化
## 引入模版
有時候一些代碼是在許多模版中都用到的。如果我們每次都重復的去拷貝代碼那肯定不符合項目的規范。一般我們可以把這些重復性的代碼抽取出來,就類似于Python中的函數一樣,以后想要使用這些代碼的時候,就通過`include`包含進來。這個標簽就是`include`。示例代碼如下:
```
<pre class="calibre12">```
# header.html
<span class="hljs-tag"><<span class="hljs-class">p</span>></span>我是header<span class="hljs-tag"></<span class="hljs-class">p</span>></span>
# footer.html
<span class="hljs-tag"><<span class="hljs-class">p</span>></span>我是footer<span class="hljs-tag"></<span class="hljs-class">p</span>></span>
# main.html
{% include 'header.html' %}
<span class="hljs-tag"><<span class="hljs-class">p</span>></span>我是main內容<span class="hljs-tag"></<span class="hljs-class">p</span>></span>
{% include 'footer.html' %}
```
```
`include`標簽尋找路徑的方式。也是跟`render`渲染模板的函數是一樣的。
默認`include`標簽包含模版,會自動的使用主模版中的上下文,也即可以自動的使用主模版中的變量。如果想傳入一些其他的參數,那么可以使用`with`語句。示例代碼如下:
```
<pre class="calibre12">```
# header.html
<span class="hljs-tag"><<span class="hljs-class">p</span>></span>用戶名:{{ username }}<span class="hljs-tag"></<span class="hljs-class">p</span>></span>
# main.html
{% include "header.html" with username='huangyong' %}
```
```
## 模板繼承:
在前端頁面開發中。有些代碼是需要重復使用的。這種情況可以使用`include`標簽來實現。也可以使用另外一個比較強大的方式來實現,那就是模版繼承。模版繼承類似于`Python`中的類,在父類中可以先定義好一些變量和方法,然后在子類中實現。模版繼承也可以在父模版中先定義好一些子模版需要用到的代碼,然后子模版直接繼承就可以了。并且因為子模版肯定有自己的不同代碼,因此可以在父模版中定義一個block接口,然后子模版再去實現。以下是父模版的代碼:
```
<pre class="calibre12">```
{% load static %}
<span class="hljs-class"></span>
<span class="hljs-tag"><<span class="hljs-class">html</span> <span class="hljs-class">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-class">head</span>></span>
<span class="hljs-tag"><<span class="hljs-class">link</span> <span class="hljs-class">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-class">href</span>=<span class="hljs-string">"{% static 'style.css' %}"</span> /></span>
<span class="hljs-tag"><<span class="hljs-class">title</span>></span>{% block title %}我的站點{% endblock %}<span class="hljs-tag"></<span class="hljs-class">title</span>></span>
<span class="hljs-tag"></<span class="hljs-class">head</span>></span>
<span class="hljs-tag"><<span class="hljs-class">body</span>></span>
<span class="hljs-tag"><<span class="hljs-class">div</span> <span class="hljs-class">id</span>=<span class="hljs-string">"sidebar"</span>></span>
{% block sidebar %}
<span class="hljs-tag"><<span class="hljs-class">ul</span>></span>
<span class="hljs-tag"><<span class="hljs-class">li</span>></span><span class="hljs-tag"><<span class="hljs-class">a</span> <span class="hljs-class">href</span>=<span class="hljs-string">"/"</span>></span>首頁<span class="hljs-tag"></<span class="hljs-class">a</span>></span><span class="hljs-tag"></<span class="hljs-class">li</span>></span>
<span class="hljs-tag"><<span class="hljs-class">li</span>></span><span class="hljs-tag"><<span class="hljs-class">a</span> <span class="hljs-class">href</span>=<span class="hljs-string">"/blog/"</span>></span>博客<span class="hljs-tag"></<span class="hljs-class">a</span>></span><span class="hljs-tag"></<span class="hljs-class">li</span>></span>
<span class="hljs-tag"></<span class="hljs-class">ul</span>></span>
{% endblock %}
<span class="hljs-tag"></<span class="hljs-class">div</span>></span>
<span class="hljs-tag"><<span class="hljs-class">div</span> <span class="hljs-class">id</span>=<span class="hljs-string">"content"</span>></span>
{% block content %}{% endblock %}
<span class="hljs-tag"></<span class="hljs-class">div</span>></span>
<span class="hljs-tag"></<span class="hljs-class">body</span>></span>
<span class="hljs-tag"></<span class="hljs-class">html</span>></span>
```
```
這個模版,我們取名叫做`base.html`,定義好一個簡單的`html`骨架,然后定義好兩個`block`接口,讓子模版來根據具體需求來實現。子模板然后通過`extends`標簽來實現,示例代碼如下:
```
<pre class="calibre12">```
{% extends "base.html" %}
{% block title %}博客列表{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<span class="hljs-tag"><<span class="hljs-class">h2</span>></span>{{ entry.title }}<span class="hljs-tag"></<span class="hljs-class">h2</span>></span>
<span class="hljs-tag"><<span class="hljs-class">p</span>></span>{{ entry.body }}<span class="hljs-tag"></<span class="hljs-class">p</span>></span>
{% endfor %}
{% endblock %}
```
```
**需要注意的是:extends標簽必須放在模版的第一行。**
**子模板中的代碼必須放在block中,否則將不會被渲染。**
如果在某個`block`中需要使用父模版的內容,那么可以使用`{{block.super}}`來繼承。比如上例,`{%block title%}`,如果想要使用父模版的`title`,那么可以在子模版的`title block`中使用`{{ block.super }}`來實現。
在定義`block`的時候,除了在`block`開始的地方定義這個`block`的名字,還可以在`block`結束的時候定義名字。比如`{% block title %}{% endblock title %}`。這在大型模版中顯得尤其有用,能讓你快速的看到`block`包含在哪里。
- Introduction
- 第一章:學前準備
- 第一節:虛擬環境
- 第二節:準備工作
- 第三節:Django介紹
- 第四節:URL組成部分
- 第二章:URL與視圖
- 第一節:第一個Django項目
- 第二節:視圖與URL分發器
- 第三章:模板
- 第一節:模板介紹
- 第二節:模板變量
- 第三節:常用標簽
- 第四節:常用過濾器
- 第五節:自定義過濾器
- 第七節:模版結構優化
- 第八節:加載靜態文件
- 第四章:數據庫
- 第一節:MySQL相關軟件
- 第二節:數據庫操作
- 第三節:ORM模型
- 第四節:模型常用字段
- 第五節:外鍵和表關系
- 第六節:增刪改查操作
- 第七節:查詢操作
- 第八節:QuerySet API
- 第九節:ORM模型遷移
- 第十節:ORM作業
- 第十一節:ORM作業參考答案
- 第十二節:Pycharm連接數據庫
- 第五章:視圖高級
- 第一節:限制請求method
- 第二節:頁面重定向
- 第三節:HttpRequest對象
- 第四節:HttpResponse對象
- 第五節:生成CSV文件
- 第六節:類視圖
- 第七節:錯誤處理
- 第六章:表單
- 第一節:表單概述
- 第二節:用表單驗證數據
- 第三節:ModelForm
- 第四節:文件上傳
- 第七章:cookie和session
- 第八章:上下文處理器和中間件
- 第一節:上下文處理器
- 第二節:中間件
- 第九章:安全
- 第一節:CSRF攻擊
- 第二節:XSS攻擊
- 第三節:點擊劫持攻擊
- 第四節:SQL注入
- 第十章:信號
- 第一節:什么是信號
- 第十一章:驗證和授權
- 第一節:概述
- 第二節:用戶對象
- 第三節:權限和分組
- 第十二章:Admin系統
- 第十三章:Django的緩存
- 第十四章:memcached
- 第十五章:Redis