模板介紹
- 模板致力於表達外觀,而不是程序邏輯;設計實現了業務邏輯view 與顯示內容template的解耦
- 模板包含兩部分
- 靜態:包含html、css、js
- 動態:就是模板語言(簡寫DTL,定義在django.template)
# 模板處理
1.加載: 根據給定的路徑找到模板文件,編譯後放在內存中
2.渲染: 使用上下文數據對模板傳值並返回動態生成的網頁
模板配置:'DIRS': [os.path.join(BASE_DIR, 'templates')]
模板語言
- 作用:獲取、處理傳入到模板中的上下文數據,動態的產生頁面內容
- 包含4種類型:1.變量, 2.標籤 , 3.過濾器(可自定義), 4.註釋
作用:計算並輸出上下文傳入的數據.
語法:{{變量}}
變量名規則:由字母、數字、下劃線和點組成(不能以下劃線開頭).
1.字典book['name']
2.先屬性後方法,將book當作對象,查找屬性name,如果沒有再查找方法那麼()
3.如果是格式爲book.0則解析爲列表book[0]
如果變量不存在則插入空字符串"".
在模板中調用方法時不能傳遞參數(使用帶參數方法,需要使用過濾器)
語法:{% 代碼段 %}
- for循環標籤
{% for item in 列表 %} 執行循環邏輯
{{ forloop.counter }}獲取當前是第幾次循環,
從1開始 {% empty %} 列表爲空或不存在時執行此邏輯
{% endfor %}
- if標籤
{% if ... %}
邏輯1
{% elif ... %}
邏輯2
{% else %}
邏輯3
{% endif %}
- 比較運算符標籤 ,左右兩側必須有空格
==, !=, <, >, <= , >=
- 布爾運算符標籤
and, or, not
作用:模板語言中不允許帶參數的函數,如果要對變量進行處理,就需要使用過濾器
使用管道符號 | 來應用過濾器,用於進行計算、轉換操作,可以使用在變量、標籤中
一個參數時:變量|過濾器
兩個參數時:變量|過濾器:參數
length: 返回字符串、列表、元組、字典的元素個數(變量 | length)
default: 如果變量不存在時則返回默認值(變量 | default: 默認值)
date: 用於對日期類型的值進行字符串格式化
- Y表示年,格式爲4位,y表示兩位的年
- m表示月,格式爲01,02,12等
- j表示日,格式爲1,2等
- H表示時,24進制,表示12進制的是時
- i表示分,爲0-59
- s表示秒, 爲0-59
日期 | date:'Y年m月j日 H時i分s秒'
* 當內建過濾器無法滿足需求時,需要自定義過濾器
* 過濾器就是python中的函數,註冊後就可以在模板中當做過濾器使用
* 自定義過濾器的python包,必須命名爲templatetags
* 創建註冊對象,必須命名爲register
* 在模板中使用模板註釋,註釋掉某一段代碼,那麼這段代碼不會被編譯,不會輸出到客戶端;註釋可以包含任何模板代碼,有效的或者無效的都可以註釋掉
- html註釋只能註釋html內容,不能註釋模板語言
單行註釋
{
多行註釋使用comment標籤
{% comment %}
...
{% endcomment %}
模板繼承
- 作用:主要是爲了提高代碼重用,減輕開發人員的工作量
- 典型應用: 網站的頭部、尾部信息
# 父模板
- 如果發現一段代碼在多個模板中出現,那就應該把這段代碼內容定義到父模板中
- 父模板中也可以使用上下文中傳遞過來的數據
- 父模板定義在templates文件目錄
- block標籤: 用於在父模板中預留區域,留給子模板填充差異性的內容
- 可以給預留區域定義名字,但多個預留區域名字布恩那個相同
- 爲了更好的可讀性,建議給endblock標籤寫上名字,這個名字與對應的block標籤名字相同
{% block 名稱 %}
預留區域,可以編寫默認內容,也可以沒有默認內容
{% endblock 名稱 %}
# 子模板
- 子模板定義在templates/應用 文件目錄下
- extends標籤:繼承,寫在子模板文件的第一行
- 子模板不用填充父模板中的所有預留區域,如果子模板沒有填充,則使用父模板定義的默認值
{% block 名稱 %}
實際填充內容
{{block.super}} 用於獲取父模板中block的內容,也可以不獲取
{% endblock 名稱 %}
# 注意點:
1.子模板繼承父模板之後,本身原有的內容是不起作用的
2.父模板不能把上下文傳給子模板,只能繼承內容不繼承上下文
HTML轉義
- 在視圖中,通過調用模板傳遞上下文,模板對上下文傳遞的字符串進行輸出時,會對以下字符自動轉義
- 作用:轉義後標記代碼(標籤)不會被直接解釋執行,而是被直接呈現,防止客戶端通過嵌入js代碼攻擊網站
小於號 < 轉換爲 <
大於號 > 轉換爲 >
單引號 ' 轉換爲 '
雙引號 " 轉換爲 "
與符號 & 轉換爲 &
禁止HTML轉義
- 過濾器escape:可以實現對變量的HTML轉義,默認模板就會轉義,一般省略;{{變量 | escape}}
- 過濾器safe : 禁用轉義,告訴模板這個變量是安全的,可以解釋執行;{{變量 | safe}}
- 標籤autoescape : 設置一段代碼都禁用轉義,接受on(啓用轉義)、 off(禁用轉義)參數
- 其他
1.對於在模板中硬編碼<, >, ‘, “, &不會被轉義
2.在模板中硬編碼如果希望出現轉義的效果,則需要手動編碼轉義
CSRF
- CSRF全拼爲Cross Site Request Forgery, 譯爲跨站請求僞造
- CSRF 指攻擊者盜用了你的身份,以你的名義發送惡意請求;造成個人隱私泄漏以及財產安全
1.Django 第一次響應來自某個客戶端的請求時,會在服務器端隨機生成一個 token,把這個 token 放在 cookie 裏。然後每次 POST 請求都會帶上這個 token,這樣就能避免被 CSRF 攻擊
2.在返回的 HTTP 響應的 cookie 裏,django 會爲你添加一個 csrftoken 字段,其值爲一個自動生成的 token
3.在所有的 POST 表單時,必須包含一個 csrfmiddlewaretoken 字段 (只需要在模板里加一個 csrf_token標籤, django 就會自動幫我們生成)
4.在處理 POST 請求之前,django 會驗證這個請求的 cookie 裏的 csrftoken 字段的值和提 交的表單裏的 csrfmiddlewaretoken 字段的值是否一樣。如果一樣,則表明這是一個合法的請求,否則,這個請求可能是來自於別人的 csrf 攻擊,返回 403 Forbidden.
驗證碼
- 在用戶註冊、登錄頁面,爲了防止暴力請求,可以加入驗證碼功能,如果驗證碼錯誤,則不需要繼續處理,可以減輕業務服務器、數據庫服務器的壓力
反向解析
url = (r'^', include('Book.urls', namespace='book')),
url = (r'^fan123/$', fan1, name='fan1'),
url(r'^fan123/(\d+)/(\d+)/$', fan2, name='fan2')
url(r'^fan123/(?P<num1>\d+)/(?P<num2>\d+)/$', fan3, name='fan3')
<a href='{% url "book:fan1" %}}'></a>
<a href='{% url "book:fan2" 18 188 %}'></a>
<a href='{% url "book:fan3" num1=18 num2=188 %}'></a>
<a href='{% url "book:fan3" 18 188 %}'></a>
from django.core.urlresolvers import reverse
return redirect(reverse('book:fan1'))
return redirect(reverse('book:fan2', args=(18, 188)))
return redirect(reverse('book:fan3', args=(18, 188)))
return redirect(reverse('book:fan3',kwargs=('num1':18, 'num2':188)))
配置流程
# 創建項目
django-admin startproject 項目名稱
# 創建應用
cd BookManager/
python manage.py startapp 應用名稱
#修改解釋器路徑
/home/python/.virtualenvs/py3_django/bin/python
# 運行服務器
python manage.py runserver
# 生成、執行遷移
python manage.py makemigrations
python manage.py migrate
# 界面本地化
LANGUAGE_COOE="zh-Hans"
TIME_ZONE="Asia/Shanghai"
# 創建管理員
python manage.py createsuperuser
# 配置URL
## 項目
url(r'^', include('Book.urls')),
## 應用
url(r'^booklist/$', bookList),
# 配置mysql數據庫
## __init__下
import pymysql
pymysql.install_as_MySQLdb()
## settings下
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'Bookdb',
'HOST': '192.168.80.132',
'PORT': '3306',
'USER': 'root',
'PASSWORD': 'mysql',
}
}
# 創建模板文件夾templates,設置模板路徑
"DIRS":[os.path.join(BASE_DIR, "templates")]
# 創建靜態文件夾static,設置文件路徑
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
# 上傳文件,在static下創建media,其下再創建Book
## 在settings配置文件上傳時保存到的路徑
MEDIA_ROOT=os.path.join(BASE_DIR, 'static/media')
# 錯誤視圖配置(線上模式)
DEBUG = False
ALLOWED_HISTS = ['*']
# 配置自定義過濾器
## 在應用下新建templatetags(必須此名)包,在包下新建py文件定義過濾器函數,註冊對象必須命名爲register
## 加載過濾器{load py文件名}
# 定義父子模板
## 父模板定義在templates文件目錄下
##子模板定義在templates/應用文件目錄下
## 子模板中使用{% extends '父模板名' %}
# 自定義中間件
在應用中新建middleware.py文件,在文件中定義類TestMiddleware
在settings.py下配置中間件
MIDDLEWARE_CLASSES= [
# 註冊自定義中間件
'Book.middleware.TestMiddleware',
]
# 站點管理中重寫模板
在templates 目錄下創建 admin目錄
再在admin文件下創建base_site.html
{% extends "admin/base.html" %}
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block branding %}
{#<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1>#}
{# 自定義內容 #}
<h1 id="site-name"><a href="{% url 'admin:index' %}">電商項目</a></h1>
{% endblock %}
{% block nav-global %}{% endblock %}