Python web架構要點
web 應用程式的本質:
1、接收并解析HTTP請求,擷取具體的請求資訊
2、處理本次的HTTP請求,即完成本次請求的業務邏輯處理
3、構造并傳回處理結果 —— HTTP響應
Django介紹
特點:
1、提供項目工程管理的自動化腳本工具
2、資料庫orm支援(對象管理映射)
3、模闆
4、表單
5、Admin管理站點
6、檔案管理
7、認證權限
8、session機制
9、緩存
MVT模式:
核心思想:分工、解耦,讓不同的代碼塊之間降低耦合,增強代碼的可擴充性和可移植性,實作向後相容。(高聚合,低耦合)
建立Django工程:
django-admin startproject 工程名稱
運作伺服器的指令:
python manage.py runserver (ip:端口)
ip和端口可省略,預設為:127.0.0.1,:8000
建立子應用:
1、 python manage.py startapp 子應用名稱(此時manage.py是建立工程時自動生成的管理檔案)
檔案類型說明:
- admin.py:跟網站的背景管理站點配置相關
- app.py :用于配置目前子應用的相關資訊
- migrations:該目錄用于存放資料庫遷移曆史檔案
- models.py:用于存放資料庫模型類
- test.py:用于開發測試用例,編寫單元測試
-
views.py:編寫web應用視圖
2、建立出來的子應用目錄檔案雖然被放到了工程項目目錄中,但是django工程并不能立即直接使用該子應用,需要注冊安裝後才能使用。
即:将子應用的配置資訊檔案apps.py中的Config類添加到INSTALLED_APPS清單中。
建立視圖
Django視圖定義在views檔案中
視圖函數的第一個傳入的參數必須定義,用于接受Django構造的包含了請求資料的HttpReqeust對象,通常名為request。
定義路由URL
- 在子應用中建立一個urls.py的檔案用于存放該應用的路由。
-
在users/urls.py檔案中定義路由資訊:格式:url(路徑, 視圖)
url(r’^index/$’, views.index),
- 在工程總路由demo/urls.py中添加子應用的路由資料:格式:url(r’^users/’, include(‘users.urls’))
- 重新啟動運作Django程式:python manage.py runserver
配置靜态檔案與路由
配置檔案
1、BASE_DIR:BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file))),目前工程的根目錄,Django會依此來定位工程内的相關檔案,我們也可以使用該參數來構造檔案路徑。
2、DEBUG:線上運作時不能在此模式下運作,修改為Flase, Django在調試模式下預設不提供靜态檔案服務
3、本地語言與時區:簡體中文和上海
靜态檔案
為提供靜态檔案,需要配置兩個參數
STATICFILES_DIRS 存放查找靜态檔案的目錄
STATIC_URL 通路靜态檔案的URL字首
步驟:
- 在項目根目錄下建立static_files目錄來儲存靜态檔案
-
在demo/settings.py中修改靜态檔案的兩個參數STATIC_URL = ‘/static/’
STATICFILES_DIRS = [
os.path.join(BASE_DIR, ‘static_files’)]
- 此時在static_files添加的任何靜态檔案都可以使用網址 /static/檔案在static_files中的路徑 來通路了
路由說明
1、路由定義位置
兩種方式:
-
Django的主要路由資訊定義在工程同名目錄下的urls.py檔案中,該檔案是Django解析路由的入口。
每個子應用為了保持相對獨立,可以在各個子應用中定義屬于自己的urls.py來儲存該應用的路由。然後用主路由檔案包含各應用的子路由資料
- 也可将工程的全部路由資訊都定義在主路由檔案中,子應用不再設定urls.py
2、路由解析順序
Django在接收到一個請求時,從主路由檔案中的urlpatterns清單中以由上至下的順序查找對應路由規則,如果發現規則為include包含,則再進入被包含的urls中的urlpatterns清單由上至下進行查詢。值得關注的由上至下的順序,有可能會使上面的路由屏蔽掉下面的路由,帶來非預期結果。
3、 路由命名
- 在使用include函數定義路由時,可以使用namespace參數定義路由的命名空間:命名空間的作用:避免不同應用中的路由使用了相同的名字發生沖突,使用命名空間差別開。url(r’^users/’, include(‘users.urls’, namespace=‘users’)),
-
在定義普通路由時,可以使用name參數指明路由的名字
4、reverse反解析
使用reverse函數,可以根據路由名稱,傳回具體的路徑
5、路徑結尾斜線/的說明
- Django中定義路由時,通常以斜線/結尾,其好處是使用者通路不以斜線/結尾的相同路徑時,Django會把使用者重定向到以斜線/結尾的路徑上,而不會傳回404不存在
- 雖然路由結尾帶/能帶來上述好處,但是卻違背了HTTP中URL表示資源位置路徑的設計理念。是否結尾帶/以所屬公司定義風格為準。
app應用配置
-
在每個應用目錄中都包含了apps.py檔案,用于儲存該應用的相關資訊。
在建立應用時,Django會向apps.py檔案中寫入一個該應用的配置類
-
我們将此類添加到工程settings.py中的INSTALLED_APPS清單中,表明注冊安裝具備此配置屬性的應用。
AppConfig.name 屬性表示這個配置類是加載到哪個應用的,每個配置類必須包含此屬性,預設自動生成。
AppConfig.verbose_name 屬性用于設定該應用的直覺可讀的名字,此名字在Django提供的Admin管理站點中會顯示:class UsersConfig(AppConfig):
name = ‘users’
verbose_name = ‘使用者管理’
請求與響應
請求request傳遞參數
向伺服器傳參的幾種路徑:
提取URL的特定部分,如/weather/beijing/2018,可以在伺服器端的路由中用正規表達式截取;
查詢字元串(query string),形如key1=value1&key2=value2;
請求體(body)中發送的資料,比如表單資料、json、xml;
在http封包的頭(header)中。
1、url路徑參數
- 在定義路由URL時,可以使用正規表達式提取參數的方法從URL中擷取請求參數,Django會将提取的參數直接傳遞到視圖的傳入參數中。
2、Django中的QueryDict對象
- HttpRequest對象的屬性GET、POST都是QueryDict類型的對象
- 方法get():如果一個鍵同時擁有多個值将擷取最後一個值
- 方法getlist():根據鍵擷取值,值以清單傳回,可以擷取指定鍵的所有值
3、查詢字元串Query String
擷取請求路徑中的查詢字元串參數(形如?k1=v1&k2=v2),可以通過request.GET屬性擷取,傳回QueryDict對象。:例如:
#/qs/?a=1&b=2&a=3
def qs(request):
a = request.GET.get(‘a’)
b = request.GET.get(‘b’)
alist = request.GET.getlist(‘a’)
print(a) # 3
print(b) # 2
print(alist) # [‘1’, ‘3’]
return HttpResponse(‘OK’)
注意:查詢字元串不區分請求方式,即假使用戶端進行POST方式的請求,依然可以通過request.GET擷取請求中的查詢字元串資料。
4、請求體
可以發送請求體資料的請求方式有POST、PUT、PATCH、DELETE
Django預設開啟了CSRF防護,會對上述請求方式進行CSRF防護驗證,在測試時可以關閉CSRF防護機制,方法為在settings.py檔案中注釋掉CSRF中間件
- 表單類型 Form Data
-
非表單類型:Non-Form Data
Django無法自動解析,可以通過request.body屬性擷取最原始的請求體資料,自己按照請求體格式(JSON、XML等)進行解析。request.body傳回bytes類型。
import json
def get_body_json(request):
json_str = request.body
json_str = json_str.decode() # python3.6 無需執行此步
req_data = json.loads(json_str)
print(req_data[‘a’])
print(req_data[‘b’])
return HttpResponse(‘OK’)
5、請求頭:
可以通過request.META屬性擷取請求頭headers中的資料,request.META為字典類型
6、其他常用的HttpRequest對象屬性
method:一個字元串,表示請求使用的HTTP方法,常用值包括:‘GET’、‘POST’。
user:請求的使用者對象。
path:一個字元串,表示請求的頁面的完整路徑,不包含域名和參數部分。
encoding:一個字元串,表示送出的資料的編碼方式。
如果為None則表示使用浏覽器的預設設定,一般為utf-8。
這個屬性是可寫的,可以通過修改它來修改通路表單資料使用的編碼,接下來對屬性的任何通路将使用新的encoding值。
FILES:一個類似于字典的對象,包含所有的上傳檔案。
響應 Response
HttpRequest對象由Django建立,HttpResponse對象由開發人員建立。
-
HttpResponse
1、可以使用django.http.HttpResponse來構造響應對象。
HttpResponse(content=響應體, content_type=響應體資料類型, status=狀态碼)
2、也可通過HttpResponse對象屬性來設定響應體、響應體資料類型、狀态碼
例如:
from django.http import HttpResponse
def demo_view(request):
return HttpResponse(‘itcast python’, status=400)
或者
response = HttpResponse(‘itcast python’)
response.status_code = 400
response[‘Itcast’] = ‘Python’
return response
- HttpResponse子類
-
JsonResponse
若要傳回json資料,可以使用JsonResponse來構造響應對象
作用:幫助我們将資料轉換為json字元串
設定響應頭Content-Type為 application/json
- redirect重定向
cookie
-
設定cookie:通過HttpResponse對象中的set_cookie方法,HttpResponse.set_cookie(cookie名, value=cookie值, max_age=cookie有效期)
response.set_cookie(‘itcast1’, ‘python1’) # 臨時cookie
response.set_cookie(‘itcast2’, ‘python2’, max_age=3600) # 有效期一小時
-
讀取Cookie
可以通過HttpRequest對象的COOKIES屬性來讀取本次請求攜帶的cookie值。request.COOKIES為字典類型。
session
Django項目預設啟用Session。
- session預設存儲在資料庫中:SESSION_ENGINE=‘django.contrib.sessions.backends.db’
- 本地緩存:SESSION_ENGINE=‘django.contrib.sessions.backends.cache’
- 混合存儲,優先從本機記憶體中存取,如果沒有則從資料庫中存取。:SESSION_ENGINE=‘django.contrib.sessions.backends.cached_db’
- redis,在redis中儲存session,需要引入第三方擴充,我們可以使用django-redis來解決
-
session操作
1、寫入:request.session[‘鍵’]=值
2、讀取:request.session.get(‘鍵’,預設值)
3、清除所有的session(删除值部分):request.session.clear()
4、清除session資料(删除整條資料):request.session.flush()
5、删除session中的指定鍵及值:del request.session[“鍵”]
6、設定session有效期:request.session.set_expiry(value),
value 為None,預設有效期為兩周,有值時,機關為秒。為0時:關鍵浏覽器時過期
類視圖
類視圖的好處:
代碼可讀性好
類視圖相對于函數視圖有更高的複用性, 如果其他地方需要用到某個類視圖的某個特定邏輯,直接繼承該類視圖即可
-
類視圖的使用
定義類視圖需要繼承自Django提供的父類View,可使用from django.views.generic import View或者from django.views.generic.base import View 導入
配置路由時,使用類視圖的as_view()方法來添加
-
類視圖使用裝飾器
1、在url配置中裝飾:此種方式最簡單,但因裝飾行為被放置到了url配置中,單看視圖的時候無法知道此視圖還被添加了裝飾器,不利于代碼的完整性,不建議使用。
2、在類視圖中裝飾:在類視圖中使用為函數視圖準備的裝飾器時,不能直接添加裝飾器,需要使用method_decorator将其轉換為适用于類視圖方法的裝飾器。
method_decorator裝飾器還支援使用name參數指明被裝飾的方法
3、構造Mixin擴充類
中間件
可以使用中間件,在Django處理視圖的不同階段對輸入或輸出進行幹預。
- 定義方法:定義一個中間件工廠函數,然後傳回一個可以被調用的中間件中間件工廠函數需要接收一個可以調用的get_response對象。傳回的中間件也是一個可以被調用的對象,并且像視圖一樣需要接收一個request對象參數,傳回一個response對象
-
多個中間件執行順序:
在請求視圖被處理前,中間件由上至下依次執行
在請求視圖被處理後,中間件由下至上依次執行
資料庫
orm:django中内嵌了ORM架構,不需要直接面向資料庫程式設計,而是定義模型類,通過模型類和對象完成資料表的增删改查操作。
使用django進行資料庫開發的步驟:
- 配置資料庫連結資訊
- 在models.py中定義模型類
- 進行資料庫的遷移
- 通過類和對象完成資料庫的增删改查操作
配置
Django預設使用sqlite資料庫,
- 使用MySql資料庫首先需要安裝驅動程式:pip install PyMySQL
-
在django工程同名子目錄的__init__.py檔案中添加語句:from pymysql import install_as_MySQLdb
install_as_MySQLdb(),作用是:讓Django的ORM能以mysqldb的方式來調用PyMySQL
- 修改DATABASES配置資訊:
- 在mysql中建立資料庫
定義模型類
模型類被定義在"應用/models.py"檔案中。
模型類必須繼承自Model類,位于包django.db.models中
- 定義:建立子應用,在models.py中定義模型類
- 遷移,生成遷移檔案:python manage.py makemigrations;同步到資料庫中:python manage.py migrate
- 添加測試資料,
示範工具使用
- shell工具:Django的manage工具提供了shell指令,幫助我們配置好目前工程的運作環境(如連接配接好資料庫等),以便可以直接在終端中執行測試python語句。指令:python manage.py shell; 導入模型類,以便使用
- 檢視mysql資料庫日志
資料庫的操作
- 增:
-
- 1、save:通過建立模型類對象,執行對象的save()方法儲存到資料庫;
-
- 2、通過模型類.objects.create()儲存。
- 查:
-
- get 查詢單一結果,如不存在則會抛出模型類.DoesNotExist異常;all 查詢多個結果
-
- 過濾查詢:
-
-
- 相等:exact:BookInfo.objects.filter(id_exact=1),可簡寫BookInfo.objects.filter(id=1)
-
-
-
- 模糊查詢:contains:是否包含;startswith、endswith:以指定值開頭或結尾。
-
-
-
- 空查詢:isnull:是否為null。
-
-
-
- 範圍查詢:in: BookInfo.objects.filter(id_in=[1, 3, 5])
-
-
-
-
比較查詢:gt 大于 (greater then)
gte 大于等于 (greater then equal)
lt 小于 (less then)
lte 小于等于 (less then equal)
-
-
-
-
- 日期查詢:year、month、day、week_day、hour、minute、second:對日期時間類型的屬性進行運算。
-
-
- F對象:先從django.db.models中導入:BookInfo.objects.filter(bread_gte=F(‘bcomment’))
-
- Q對象:同樣需要先導入,Q對象可以使用&、|連接配接,&表示邏輯與,|表示邏輯或;Q對象前可以使用~操作符,表示非not。
-
-
- BookInfo.objects.filter(Q(bread_gt=20) | Q(pk_lt=3));BookInfo.objects.filter(~Q(pk=3))
-
-
- 排序:order_by
- 修改:
-
- save,修改模型類的屬性,執行save()方法
-
- update,使用模型類.objects.filter().update(),會傳回受影響的行數
- 删除
-
- 執行模型裡對象的delete()方法
-
- 模型類.objects.filter().delete()
查詢集 QuerySet
查詢集,也稱查詢結果集、QuerySet,表示從資料庫中擷取的對象集合。
- 兩大特性:
-
- 惰性執行
-
- 緩存
- 限制查詢集:對查詢集進行切片後傳回一個新的查詢集,不會立即執行查詢。
模闆
配置
- 在工程中建立目錄templates
- 在settings.py配置檔案中修改TEMPLATES配置項的DIRS值
定義模闆
在templates目錄中建立一個模闆檔案,如:index.html
模闆渲染:
Django提供了一個函數render:render(request對象, 模闆檔案路徑, 模闆資料字典)
from django.shortcuts import render
def index(request):
context={‘city’: ‘北京’}
return render(request,‘index.html’,context)
模闆文法
- 模闆變量
- 模闆語句
- 過濾器
- 注釋
- 模闆繼承
Admin站點
- Django能夠根據定義的模型類自動地生成管理頁面。
使用django的管理子產品,步驟:
- 1、管理界面本地化
- 2、建立管理者,:python manag.py createsuperuser
- 3、注冊模型類:admin.site.register(BookInfo)
- 4、自定義管理頁面,定義管理類需要繼承自admin.ModelAdmin類