版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Python
Django開發(fā)實(shí)戰(zhàn)第1章初識Django框架Django的MTV設(shè)計模式Django提供的主要功能模塊Django的產(chǎn)生背景Django的產(chǎn)生背景開發(fā)Web站點(diǎn),通常需要做這樣的幾件事:構(gòu)建用戶賬戶體系,實(shí)現(xiàn)Web站點(diǎn)的登錄與注冊功能數(shù)據(jù)表模型定義及訪問功能實(shí)現(xiàn)編寫業(yè)務(wù)邏輯實(shí)現(xiàn)站點(diǎn)功能后臺管理功能路由模型實(shí)現(xiàn)功能請求映射幾乎所有的Web站點(diǎn)都需要做這樣的事,且很多功能設(shè)計都是類似或一樣的,所以,這里會引入大量的重復(fù)工作。這里存在的問題由此產(chǎn)生了Web框架的概念(思想),這也就是Django產(chǎn)生的根本原因!Django的產(chǎn)生背景Django的版本發(fā)布過程版本類型版本說明功能版本版本號定義為A.B,A.B+1等,大約每8個月發(fā)布一次,每個版本包括新功能以及對現(xiàn)有功能的改進(jìn)補(bǔ)丁版本版本號定義為A.B.C,A.B.C+1等,用來修復(fù)bug或者是安全問題,補(bǔ)丁版本是100%兼容相關(guān)的功能版本的,所以,除非是由于安全問題或者是可能造成數(shù)據(jù)丟失的情況之外,都應(yīng)該升級到最新的補(bǔ)丁版本LTS版本長期支持的版本,某些功能版本會被指定為LTS版本,比如1.8LTS版本,這類版本的安全更新時長將達(dá)到至少三年說明:Django最后一個支持Python2.7的版本是1.11LTS,而最新的Django功能版本是2.0,如果想使用最新版本的話,需要選擇Python3。Django的MTV設(shè)計模式UserControllerModelView數(shù)據(jù)庫發(fā)起請求返回響應(yīng)數(shù)據(jù)存取發(fā)送指令業(yè)務(wù)數(shù)據(jù)選擇視圖MVC設(shè)計模式的交互過程對于MVC設(shè)計模式:
M即Model,代表的是數(shù)據(jù)存取層,是對數(shù)據(jù)實(shí)體的定義和對數(shù)據(jù)的CRUD操作;
V即View,代表的是視圖層,即系統(tǒng)中選擇顯示什么和怎么顯示的部分;
C即Controller,代表的是控制層,它負(fù)責(zé)根據(jù)從View中輸入的指令,檢索Model中的數(shù)據(jù),再以一定的邏輯產(chǎn)生最終的結(jié)果輸出。Django的MTV設(shè)計模式TemplateView發(fā)起請求Model數(shù)據(jù)庫數(shù)據(jù)存取User模板渲染返回響應(yīng)業(yè)務(wù)數(shù)據(jù)發(fā)送指令MTV設(shè)計模式的交互過程對于MTV設(shè)計模式:
M即Model,數(shù)據(jù)存取層,這一層里處理所有與數(shù)據(jù)相關(guān)的事務(wù),提供在數(shù)據(jù)庫中管理(添加、修改、刪除)和查詢記錄的機(jī)制;
T即Template,表現(xiàn)層,處理頁面的顯示,即所有與表現(xiàn)相關(guān)的決定都由這一層去處理;
V即View,業(yè)務(wù)邏輯層,負(fù)責(zé)處理業(yè)務(wù)邏輯,會在適當(dāng)?shù)臅r候?qū)odel與Template組合在一起,通常被認(rèn)為是聯(lián)通M與T的橋梁。Django提供的主要功能模塊Django中的ORMORM全稱是ObjectRelationalMapping(對象關(guān)系映射),它把對象與數(shù)據(jù)庫中的表關(guān)聯(lián)起來,對象的屬性映射到表的各個字段,同時,它把對表的操作對應(yīng)到對對象的操作,實(shí)現(xiàn)了對象到SQL,SQL到對象的過程轉(zhuǎn)換。用戶模塊與權(quán)限系統(tǒng)提供了用戶、用戶組、權(quán)限等概念;維護(hù)了用戶、用戶組和權(quán)限之間的關(guān)聯(lián)關(guān)系;包含了用戶鑒權(quán)與登錄等基本功能。Admin后臺管理系統(tǒng)對系統(tǒng)中定義的數(shù)據(jù)表(Model)提供了原生的后臺管理支持,且支持對管理頁面的個性化定制,例如,針對字段值的過濾功能、搜索功能、排序功能,數(shù)據(jù)表字段的展示順序規(guī)則定義功能,字段歸類功能等等。Django提供的主要功能模塊視圖
Django視圖是MTV設(shè)計模式中的V,它在Django中的體現(xiàn)是一個Python函數(shù)或者是類,接收Web請求并返回Web響應(yīng)。模板系統(tǒng)模板系統(tǒng)用于將頁面設(shè)計的HTML代碼和用于邏輯處理的Python代碼分離開來,即做到了數(shù)據(jù)與邏輯的分離,去除不同代碼之間的耦合。優(yōu)雅的表單系統(tǒng)Form表單系統(tǒng)可以根據(jù)Form對象的定義:自動生成HTML表單元素、檢查表單數(shù)據(jù)的合法性、對不合法的表單數(shù)據(jù)進(jìn)行回顯,并提示錯誤、將表單數(shù)據(jù)轉(zhuǎn)換為對應(yīng)的Python數(shù)據(jù)類型。Django提供的主要功能模塊信號機(jī)制
Django對信號機(jī)制的解釋是:在框架的不同位置傳遞特定的消息給應(yīng)用程序執(zhí)行預(yù)定的操作。它是一種觀察者模式,或者叫做發(fā)布-訂閱模式。即當(dāng)系統(tǒng)中有event(事件)發(fā)生,一組senders(發(fā)送者)將signals(信號)發(fā)送給一組receivers(接收者),receivers再去執(zhí)行預(yù)定的操作。路由系統(tǒng)從MTV的設(shè)計模式中可以看到,用戶向Web站點(diǎn)發(fā)送請求(對應(yīng)到一個url),首先會到達(dá)“對應(yīng)的”視圖,那么,這里的視圖是怎么對應(yīng)上的呢?這就是Django路由系統(tǒng)的作用。Django利用URLconf構(gòu)建起URL模式與視圖函數(shù)之間的映射關(guān)系,即利用Django的特定配置方式,設(shè)定好哪個url可以去執(zhí)行哪一段Python代碼。中間件中間件是一個插件系統(tǒng),嵌入在Django的Request和Response之間執(zhí)行,可以對輸入和輸出內(nèi)容作出修改。中間件是業(yè)務(wù)無關(guān)的技術(shù)類組件,是用來定義處理所有請求和響應(yīng)的通用處理架構(gòu)。Django提供的主要功能模塊緩存系統(tǒng)有時訪問Web站點(diǎn)的某一個服務(wù)會發(fā)現(xiàn)執(zhí)行的比較慢,這種情況發(fā)生的原因可能是背后有復(fù)雜的計算邏輯,也可能是訪問數(shù)據(jù)庫系統(tǒng)或者文件系統(tǒng)造成的IO延遲等等。通常提高Web站點(diǎn)執(zhí)行效率的方法是使用緩存,將經(jīng)常被用戶訪問到的頁面結(jié)果保存下來,再次訪問時只需要返回緩存的結(jié)果,不會再次執(zhí)行計算等類似耗時的操作。
Django提供一個健壯的緩存系統(tǒng),實(shí)現(xiàn)了不同級別的緩存粒度:可以緩存單個視圖的結(jié)果輸出,緩存難以生成的片段,或者是緩存整個網(wǎng)站。第2章Django開發(fā)環(huán)境配置虛擬環(huán)境的安裝與配置Django的安裝與配置Python安裝與配置MySQL的安裝與配置PyCharm的安裝與配置Python的安裝與配置Python:Linux和Mac
OS
X默認(rèn)會附帶Python
2.7,需要安裝Python
3.7(Django
2.0需要的Python版本>=
3.4)pip:Python
3.4及以上版本內(nèi)置(更新:python3-mpipinstall-Upip
),常用的基本命令如下表所示命令功能pipinstall<package>
安裝packagepipinstall–U<package>
升級packagepipuninstall<package>
卸載packagepiplist
列出已經(jīng)安裝的packagepip常用的基本命令虛擬環(huán)境的安裝與配置Virtualenv:讓每個應(yīng)用/工程都有自己的運(yùn)行時環(huán)境,需要注意的地方安裝Virtualenv:pipinstallvirtualenv給BBS應(yīng)用創(chuàng)建虛擬環(huán)境(注意命名):virtualenv-p/usr/local/bin/python3.7bbs_python37
進(jìn)入虛擬環(huán)境:source./bin/activate退出虛擬環(huán)境:deactivate
Django的安裝與配置Django是Python包,使用pip工具在虛擬環(huán)境中安裝pipinstalldjango==2.0.7說明:這里指定了需要安裝的Django的版本,如果不指定,pip命令會選擇安裝最新的版本。驗(yàn)證在虛擬環(huán)境中安裝了Django,且版本是指定的以上輸出顯示,當(dāng)前的Python虛擬環(huán)境成功安裝了django模塊,且版本號是2.0.7,符合預(yù)期。MySQL的安裝與配置需要去MySQL的官方網(wǎng)站下載適合操作系統(tǒng)的安裝文件。官網(wǎng)上面提供了兩種安裝文件,一種是可以直接運(yùn)行的安裝包,另一種是需要再去配置的壓縮包。本質(zhì)上來說,這兩種文件是一樣的,最好選擇第一種安裝文件,即應(yīng)用程序安裝包。開始安裝安裝完成MySQL的安裝與配置MySQL安裝完成之后,默認(rèn)是不會加入到環(huán)境變量中去的,這里,手動把MySQL的可執(zhí)行文件加入到環(huán)境變量中去。操作系統(tǒng)環(huán)境變量說明Windows對于Windows用戶比較簡單,直接把MySQL安裝目錄下的bin加入到PATH變量中就可以了;Linux/Mac
OS
X對于Linux或MacOSX用戶而言,MySQL默認(rèn)安裝于/usr/local/mysql路徑下,需要把這個路徑下的support-files和bin目錄都加入到系統(tǒng)環(huán)境(PATH)變量中。PyCharm的安裝與配置PyCharm是一種PythonIDE,它是一個跨平臺的開發(fā)環(huán)境,官方提供Windows、macOS和Linux版本。目前,PyCharm被社區(qū)認(rèn)為是最好用的PythonIDE。從官方網(wǎng)站中下載對應(yīng)于操作系統(tǒng)的版本,由于也是一個應(yīng)用程序,直接點(diǎn)擊安裝即可。安裝完成設(shè)置面板第3章Django項目框架搭建修改項目的默認(rèn)配置初始化項目環(huán)境Django管理工具創(chuàng)建項目骨架Django管理工具創(chuàng)建項目骨架django-admin:Django提供的命令行管理工具startproject,用于創(chuàng)建Django項目的子命令,在虛擬環(huán)境中執(zhí)行命令:
django-adminstartprojectmy_bbsmanage.py,用于管理Django項目的命令行工具,完成了項目骨架的創(chuàng)建之后,進(jìn)入到my_bbs容器目錄中就可以啟動內(nèi)置的服務(wù)器運(yùn)行當(dāng)前的項目,執(zhí)行命令:
pythonmanage.pyrunserver
startproject是django-admin的子命令,用于創(chuàng)建項目。這里,使用這個子命令創(chuàng)建了my_bbs項目。正常情況下,執(zhí)行這個命令不會打印任何內(nèi)容,但是它會在當(dāng)前目錄下生成一個項目的骨架,也可以稱作是項目的容器。除了使用runserver啟動項目之外,還可以使用shell命令進(jìn)入到當(dāng)前項目的環(huán)境中去:pythonmanage.pyshellDjango管理工具創(chuàng)建項目骨架settings.py
:Django項目的配置文件BASE_DIR定義的是項目所在的完整路徑SECRET_KEY加密鹽,用于對加密數(shù)據(jù)做Hash處理DEBUG調(diào)試標(biāo)記,在開發(fā)環(huán)境中設(shè)置為trueALLOWED_HOSTS用于配置可以訪問當(dāng)前站點(diǎn)的域名INSTALLED_APPS當(dāng)前項目需要加載的app包路徑列表MIDDLEWARE需要加載的中間件列表配置ROOT_URLCONF量標(biāo)記的是當(dāng)前項目的根url配置TEMPLATES列表變量,用于項目的模板配置WSGI_APPLICATIONWSGI應(yīng)用程序?qū)ο蟮耐暾鸓ython路徑……修改項目的默認(rèn)配置配置語言環(huán)境和時區(qū)把BBS項目修改為中文簡體:LANGUAGE_CODE='zh-Hans'對時區(qū)不敏感:TIME_ZONE='Asia/Shanghai'、USE_TZ=False配置開發(fā)數(shù)據(jù)庫配置MySQL:Engine(數(shù)據(jù)庫引擎)、NAME(數(shù)據(jù)庫名稱)、USER(數(shù)據(jù)庫用戶名)、PASSWORD(數(shù)據(jù)庫名稱)、HOST(數(shù)據(jù)庫服務(wù)器地址)、PORT(數(shù)據(jù)庫服務(wù)器端口號)是由于MySQLdb不支持Python3,所以Django連接MySQL就不能再使用MySQLdb了,需要安裝mysqlclient。在虛擬環(huán)境中執(zhí)行命令:pipinstallmysqlclient
Django自帶的sqlite3不適合做應(yīng)用項目的數(shù)據(jù)庫,所以,這里用MySQL替代項目的默認(rèn)數(shù)據(jù)庫,需要修改DATABASES配置。初始化項目環(huán)境INSTALLED_APPS中定義應(yīng)用的數(shù)據(jù)庫遷移makemigrations:manage.py的子命令,生成應(yīng)用遷移文件migrate:manage.py的子命令,用于將應(yīng)用的模型定義或修改同步到數(shù)據(jù)庫中django_migrations:記錄每一次數(shù)據(jù)庫遷移動作創(chuàng)建超級用戶登錄管理后臺createsuperuser:manage.py的子命令,用于創(chuàng)建超級用戶初始化項目環(huán)境給BBS項目創(chuàng)建應(yīng)用startapp:manage.py的子命令,用于創(chuàng)建應(yīng)用Python項目中的requirements.txt文件pip
freeze:得到依賴清單pip
install:重建項目環(huán)境將項目裝載到IDE中第4章Django
ORM應(yīng)用與原理剖析Model相關(guān)的概念與使用方法Model的查詢操作API構(gòu)建post應(yīng)用需要的數(shù)據(jù)表ORM實(shí)現(xiàn)原理分析構(gòu)建post應(yīng)用需要的數(shù)據(jù)表post應(yīng)用的Models定義BaseModel:抽象Model基類,定義通用參數(shù)和通用屬性,直接繼承自django.db.models.ModelTopic:話題Model,繼承自BaseModel,從而實(shí)現(xiàn)間接繼承Comment:話題評論Model,繼承自BaseModel,從而實(shí)現(xiàn)間接繼承post應(yīng)用承載這樣的幾個功能:用戶可以在BBS站內(nèi)發(fā)表話題,稱作Topic可以針對每一個Topic發(fā)表評論,稱作Comment可以對每一個Comment支持或者反對Topic和Comment都實(shí)現(xiàn)了__str__方法,且函數(shù)的返回值也很類似,都打印了id和標(biāo)識內(nèi)容的字段,id字段是在Model定義中沒有主動指定主鍵的情況下,Django自動加上去的。構(gòu)建post應(yīng)用需要的數(shù)據(jù)表post應(yīng)用完成數(shù)據(jù)庫遷移INSTALLED_APPS:將post應(yīng)用加載到BBS項目中,將post.apps.PostConfig放在列表中的第一個執(zhí)行數(shù)據(jù)庫遷移:
pythonmanage.pymakemigrationspost:在post/migrations包下面生成遷移文件
pythonmanage.pysqlmigratepost0001:打印遷移文件執(zhí)行的SQL語句
pythonmanage.pycheck:檢查遷移SQL語句中的問題
pythonmanage.pymigrate:將Models映射為數(shù)據(jù)庫的表數(shù)據(jù)表名稱:由于在Topic和Comment中都沒有顯示的指定表名,所以,應(yīng)用Django的規(guī)則,將表名定義為,應(yīng)用名_小寫類名,即post_topic和post_comment
編寫完成了post應(yīng)用的Models定義,為了實(shí)現(xiàn)對這些Models對象的操作,需要使用manage.py提供的數(shù)據(jù)庫遷移工具將Models對象映射為數(shù)據(jù)庫中的表。Model相關(guān)的概念與使用方法Model的組成部分django.db.models.ModelMeta元數(shù)據(jù)數(shù)據(jù)表項FieldMeta元數(shù)據(jù)類屬性abstractdb_tableindexesunique_together……Field通用字段選項blankuniquenulldb_indexdb_columndefaultprimary_keychoiceshelp_text……基礎(chǔ)字段類型django.db.models.FieldIntegerFieldAutoFieldCharFieldTextFieldBooleanFieldDateFieldDateTimeFieldEmailFieldSignField……Model相關(guān)的概念與使用方法三種關(guān)系字段類型ForeignKeyOneToOneFieldManyToManyFieldModel的繼承模型抽象基類多表繼承代理模型Model的查詢操作API創(chuàng)建Model實(shí)例對象返回單實(shí)例的查詢方法使用save方法創(chuàng)建Model實(shí)例使用create方法創(chuàng)建Model實(shí)例使用get查詢使用get_or_create查詢Model的查詢操作API返回RawQuerySet的查詢方法返回QuerySet的查詢方法>>>Topic.objects.all():使用all方法獲取所有的數(shù)據(jù)記錄>>>Topic.objects.reverse():使用reverse方法獲取逆序數(shù)據(jù)記錄>>>Topic.objects.order_by('-title','created_time'):使用order_by方法自定義排序規(guī)則>>>
Comment.objects.filter(up__gte=30):使用filter方法過濾數(shù)據(jù)記錄>>>Comment.objects.exclude(up__lt=29):使用exclude方法反向過濾>>>Comment.objects.values('id','up'):使用values方法獲取字典結(jié)果>>>Comment.objects.values_list(‘id’,'up'):使用values_list方法獲取元組結(jié)果>>>Comment.objects.all()[:2]:對QuerySet進(jìn)行切片>>>
Topic.objects.raw('SELECTidFROMpost_topicWHEREtitle=%s',['firsttopic'])>>>Comment.objects.raw('SELECT*FROMpost_comment')[0]:RawQuerySet支持索引和切片Model的查詢操作API返回其他類型的查詢方法存在關(guān)聯(lián)關(guān)系的查詢>>>Comment.objects.filter(id__gt=1).count():返回QuerySet的對象數(shù)量>>>Comment.objects.filter(id__gt=1).exists():判斷QuerySet是否包含對象>>>Comment.objects.filter(id=1).update(up=90,down=33):使用update方法更新Model實(shí)例>>>Topic.objects.filter(id__lte=2).delete():使用delete方法刪除Model實(shí)例>>>ment_set.filter(content='verygood!'):Model的反向查詢>>>Comment.objects.filter(topic__title__contains='first'):跨關(guān)聯(lián)關(guān)系查詢Model的查詢操作APIF和Q查詢聚合和分組查詢>>>Comment.objects.filter(up__lte=F('down')):要查詢up小于等于down的Comment>>>Comment.objects.filter(up__gt=F('down')*2):查詢所有up值大于down值2倍的Comment對象>>>Topic.objects.filter(Q(title__contains='topic')):查詢title中包含topic的所有Topic對象>>>Comment.objects.filter(topic=1).aggregate(Sum('up')):首先得到id為1的Topic的Comment對象,之后,計算up值的加和>>>Comment.objects.values('topic_id').annotate(Sum('up')).order_by():得到每一個Topic的所有Comment的up加和ORM實(shí)現(xiàn)原理分析Python元類類是用來生成對象的、類也是對象、元類是用來創(chuàng)建類的type中定義了創(chuàng)建類的三要素:類名、父類、屬性字典Python描述符描述符協(xié)議:__get__、__set__、__delete__為什么要繼承自models.Model自動添加的自增主鍵自動添加的查詢管理器Manager是怎么實(shí)現(xiàn)的ORM實(shí)現(xiàn)原理分析一次完整的ORM實(shí)現(xiàn)過程Topic.objects.filter(id__lte=2)開始安裝ManagerModel與Manager進(jìn)行掛鉤Manager調(diào)用QuerySet的filter方法驗(yàn)證和解析filter參數(shù)獲取對應(yīng)的Complier生成sql并執(zhí)行QuerySet將返回結(jié)果進(jìn)行to
python的格式轉(zhuǎn)換由Query完成To
Python
Object結(jié)束QuerySet.filter第5章Django管理后臺使用管理后臺操作Model對象實(shí)例使用ModelAdmin自定義管理后臺將Model注冊到管理后臺管理后臺實(shí)現(xiàn)原理分析將Model注冊到管理后臺啟用管理后臺的準(zhǔn)備工作settings.py文件中的配置:Admin同樣是Django的一個應(yīng)用,除了要在INSTALLED_APPS中加載自身之外,還有依賴應(yīng)用、中間件應(yīng)用數(shù)據(jù)庫遷移:既然是應(yīng)用,就可能定義了Model。Admin應(yīng)用在數(shù)據(jù)庫遷移過程中只創(chuàng)建了一張表:django_admin_log,用于記錄通過在管理后臺中完成的對Model的添加、更改和刪除操作。django_admin_log表結(jié)構(gòu)將Model注冊到管理后臺admin.py:manage的startapp命令在創(chuàng)建post應(yīng)用的時候會自動的創(chuàng)建admin.py文件,想要把自定義的Model注冊到管理后臺,就需要在這個文件中進(jìn)行聲明實(shí)現(xiàn)Model的注冊需要注冊的Model:Topic、Comment(post應(yīng)用中定義的)Model在管理后臺中顯示的名稱:可以通過Meta元數(shù)據(jù)指定fromdjango.contribimportadminfrompost.modelsimportTopic,Commentadmin.site.register([Topic,Comment])自定義Model顯示的名稱使用管理后臺操作Model對象實(shí)例管理后臺中的基本操作ChangeList:管理后臺中列出的Model對象實(shí)例的頁面Topic的ChangeList頁面動作工具欄:常被用于對實(shí)例對象的批處理操作,目前只有一個動作可以使用:“刪除所選的話題”,勾選實(shí)例,點(diǎn)擊執(zhí)行,可以將其從數(shù)據(jù)表中刪除。Model實(shí)例對象列表:這里會展示Topic對應(yīng)數(shù)據(jù)表的數(shù)據(jù)記錄,數(shù)據(jù)記錄的名稱取自__str__函數(shù)的返回值。Model實(shí)例對象總數(shù):位于實(shí)例列表的下方(如圖中顯示的“3話題”),Django會使用SELECTCOUNT(*)的方式獲取記錄總數(shù)。增加Model實(shí)例對象:位于頁面的右上角,點(diǎn)擊按鈕即可跳轉(zhuǎn)到Model的添加頁面。使用管理后臺操作Model對象實(shí)例管理后臺中的基本操作ChangeForm:可以實(shí)現(xiàn)編輯Model對象的頁面Topic的ChangeForm頁面對于ChangeForm頁面,需要知道它的一些重要特性:字段展示的順序與在Model中定義的順序相同,但是需要注意,主鍵和不可編輯的字段不會顯示。字段展示的控件由字段類型決定,例如字符類型的title用文本框展示、布爾類型的is_online用復(fù)選框展示等等。字段下方的文字提示由字段定義的help_text參數(shù)指定,例如title字段顯示的“話題標(biāo)題”。對字段的修改內(nèi)容如果不合法,頁面會給出錯誤提示。頁面最下方的按鈕實(shí)現(xiàn)字面意思的功能,對于刪除操作需要注意,級聯(lián)刪除的特性可能會導(dǎo)致其他Model對象實(shí)例被刪除。右上角的歷史按鈕可以查看從當(dāng)前管理頁面操作當(dāng)前實(shí)例對象的記錄。使用管理后臺操作Model對象實(shí)例django_admin_log:記錄管理后臺操作歷史的log表管理后臺操作歷史管理后臺展示變更歷史:在ChangeForm頁面,點(diǎn)擊頁面右上角的“歷史”按鈕進(jìn)入到變更歷史頁Model實(shí)例對象變更歷史django_admin_log表中記錄的實(shí)例變更歷史使用ModelAdmin自定義管理后臺注冊Model到Admin的兩種方式ModelAdmin的常用屬性register方法register裝飾器利用actions豐富動作工具欄利用list_display修改ChangeList的顯示列利用search_fields給ChangeList添加搜索框利用list_filter給ChangeList添加過濾器利用ordering重新定義Model實(shí)例的順序分頁相關(guān)的屬性利用get_queryset限制返回的數(shù)據(jù)記錄利用fields自定義顯示Model的字段利用fieldsets將ChangeForm中的字段分組顯示利用readonly_fields將部分字段設(shè)置為只讀利用raw_id_fields降低數(shù)據(jù)庫檢索開銷利用save_model定制實(shí)例對象的保存操作管理后臺實(shí)現(xiàn)原理分析Python裝飾器contenttypes應(yīng)用分析簡單裝飾器帶參數(shù)的裝飾器ContentType可以動態(tài)的訪問Model對象Django內(nèi)置應(yīng)用,記錄項目中所有app和model的對應(yīng)關(guān)系,并記錄于ContentType中model_class方法用于獲取當(dāng)前ContentType實(shí)例所對應(yīng)的Model對象get_object_for_this_type通過傳遞關(guān)鍵字參數(shù)可以獲取到Model實(shí)例對象get_all_objects_for_this_type根據(jù)提供的關(guān)鍵字參數(shù)返回QuerySetget_for_id通過id獲取ContentType實(shí)例對象get_for_model根據(jù)傳遞的Model或Model實(shí)例獲取對應(yīng)的ContentType實(shí)例對象裝飾器本質(zhì)上是一個函數(shù)或類,它的返回值也是一個函數(shù)或類。第6章視圖視圖的高級特性和快捷方法基于類的通用視圖視圖初探視圖工作原理分析視圖初探定義第一個視圖views.py:創(chuàng)建post應(yīng)用時,由Django自動創(chuàng)建,同時Django也建議視圖定義在這個文件中,一個最簡單的視圖:每一個視圖都會接收一個請求,對請求進(jìn)行自定義處理,最后返回一個響應(yīng),這就已經(jīng)包含了一個視圖的完整定義了。fromdjango.httpimportHttpResponsedefhello_django_bbs(request):
html="<h1>HelloDjangoBBS</h1>"
returnHttpResponse(html)這段代碼非常簡單,只有四句話,但是已經(jīng)包含了一個視圖的完整功能了。解釋如下:引入HttpResponse,作為視圖的返回類型視圖函數(shù)聲明,當(dāng)前的函數(shù)名是hello_django_bbs,它僅僅描述自身的用途函數(shù)內(nèi)部定義業(yè)務(wù)處理邏輯,這里簡單的定義了視圖的響應(yīng)內(nèi)容視圖最后返回一個HttpResponse對象,標(biāo)識一次Web請求的結(jié)束視圖初探視圖的請求與響應(yīng)對象HttpRequest:每當(dāng)請求到來的時候,Django就會創(chuàng)建一個攜帶有請求元數(shù)據(jù)的HttpRequest對象,傳遞給視圖函數(shù)的第一個參數(shù)。HttpRequest定義了很多屬性和方法:HttpResponse:在視圖中創(chuàng)建并作為返回對象(主動返回),HttpResponse同樣定義了很多屬性和方法:method標(biāo)識請求所使用的HTTP方法scheme標(biāo)識請求的協(xié)議類型:http(s)path當(dāng)前請求頁面的路徑GET包含GET請求中的所有參數(shù)POSTPOST請求中提交的表單數(shù)據(jù)……status_code標(biāo)識一次請求的狀態(tài)content存儲響應(yīng)內(nèi)容的二進(jìn)制字符串write方法這個方法將HttpResponse視為類文件對象,可以向其中添加響應(yīng)數(shù)據(jù)……視圖初探基于類的視圖視圖可以是函數(shù),也可以是類,類視圖同樣能夠?qū)崿F(xiàn)視圖的功能。類視圖最大的特點(diǎn)是可以利用不同的實(shí)例方法響應(yīng)不同的HTTP請求方法(GET、POST),且可以利用面向?qū)ο蟮募夹g(shù)將代碼分解為可重用的組件。一個簡單的類視圖定義FirstView繼承自View,它是所有基于類的視圖的基類。其中定義了get和post方法,映射到GET和POST請求類型。FirstView重寫了父類的dispatch方法,dispatch根據(jù)HTTP類型實(shí)現(xiàn)請求分發(fā),例如,如果是GET請求,則分發(fā)給get方法。如果View中沒有實(shí)現(xiàn)對應(yīng)請求類型的方法,則會返回HttpResponseNotAllowed。視圖初探動態(tài)路由轉(zhuǎn)換器三要素: regex:字符串類型的類屬性,根據(jù)屬性名可以猜測,這是一個正則表達(dá)式,用于匹配URL對應(yīng)位置的參數(shù)值 to_python:參數(shù)value是從URL中匹配到的參數(shù)值,通過強(qiáng)轉(zhuǎn)成對應(yīng)的類型傳遞給視圖函數(shù) to_url:將一個Python類型的對象轉(zhuǎn)換為字符串,to_python的反向操作默認(rèn)參數(shù):視圖也是普通的Python函數(shù),參數(shù)當(dāng)然也就可以有默認(rèn)值re_path:使用re_path的理由是path方法和轉(zhuǎn)換器都不能滿足需求動態(tài)路由即URL不是固定的,URL中包含了傳遞給視圖的參數(shù)變量。視圖初探給post應(yīng)用添加視圖Topic列表視圖Topic實(shí)例對象信息視圖給Topic實(shí)例對象添加評論的視圖視圖中的代碼應(yīng)該盡量簡潔,復(fù)雜的業(yè)務(wù)邏輯不應(yīng)該出現(xiàn)在視圖中,所以,通常會把邏輯或者service部分單獨(dú)放到一個文件中,例如:post_service.py。視圖的高級特性和快捷方法URL的反向解析視圖重定向reverse方法:通過URL模式的名字或可調(diào)用的視圖對象,得到視圖URL命名空間:應(yīng)用命名空間、實(shí)例命名空間redirect方法:實(shí)現(xiàn)302(臨時)或301(永久)重定向常用的快捷方法render方法:將給定的模板和上下文字典組合,渲染返回HttpResponse對象render_to_response方法:類似于renderget_object_or_404、get_list_or_404:獲取響應(yīng)或者返回404基于類的通用視圖TemplateView隨著應(yīng)用越來越多,重復(fù)性的業(yè)務(wù)邏輯也會越來越多,逐漸的會使開發(fā)過程變得枯燥乏味。Django意識到了這個問題,它將常用的功能抽象出來,給開發(fā)者提供了基于類的通用視圖。
TemplateView用于渲染模板,Django中基于類的視圖都應(yīng)該繼承自View,TemplateView也不例外,當(dāng)視圖中沒有復(fù)雜的業(yè)務(wù)邏輯,例如系統(tǒng)的引導(dǎo)頁面、歡迎頁面,使用TemplateView是非常簡單方便的。其定義如下(位于django/views/generic/base.py文件中):
classTemplateView(TemplateResponseMixin,ContextMixin,View)除了基本的View之外,TemplateView還繼承了兩個Mixin:ContextMixin:這個類中定義了一個方法:get_context_data,它返回一個字典對象,用于渲染模板上下文。通常,在使用TemplateView時都會重寫這個方法,給模板提供上下文數(shù)據(jù)。TemplateResponseMixin:這個類中定義了兩個重要的屬性:template_name和render_to_response方法。其中,template_name用于指定模板路徑,它是必須要提供的;render_to_response方法根據(jù)模板路徑和上下文數(shù)據(jù)(context)返回TemplateResponse?;陬惖耐ㄓ靡晥DRedirectView頁面重定向在Web開發(fā)中也是很常見的行為,所以,Django為重定向功能的實(shí)現(xiàn)提供了通用類視圖RedirectView。它定義于django/views/generic/base.py文件中,看一看它的定義:RedirectView的定義RedirectView中定義了四個類屬性和兩個方法:permanent:標(biāo)識是否使用永久重定向,默認(rèn)是False,所以,默認(rèn)情況下實(shí)現(xiàn)的是臨時重定向,即302響應(yīng)url:重定向的地址pattern_name:重定向目標(biāo)URL模式的名稱(即path中的name參數(shù))query_string:是否將查詢字符串拼接到新地址中,默認(rèn)為False,將丟棄原地址中的查詢字符串視圖工作原理分析解決一鍵多值問題的QueryDictMultiValueDict:dict的子類,用來處理多個值對應(yīng)相同的鍵的場景QueryDict:繼承自MultiValueDict
類視圖基類Viewhttp_method_not_allowed方法:返回405,標(biāo)識當(dāng)前的請求類型不被支持dispatch方法:根據(jù)HTTP請求類型調(diào)用View的同名函數(shù),實(shí)現(xiàn)請求分發(fā)as_view:創(chuàng)建View類實(shí)例,調(diào)用dispatch方法根據(jù)請求類型分發(fā)處理函數(shù)第7章Django模板系統(tǒng)模板系統(tǒng)語法模板系統(tǒng)工作原理分析模板系統(tǒng)基礎(chǔ)模板系統(tǒng)基礎(chǔ)模板系統(tǒng)初使用Template對象:使用字符串填充模板代碼,可能會拋出TemplateSyntaxError異常模板后端的默認(rèn)配置Context對象:傳遞字典對象用于模板的渲染(變量替換)TEMPLATES:位于settings.py文件中,列表類型,每一個元素都是一個字典對象,每個字典對象代表了配置的模板后端。字典中的key代表的含義如下:BACKEND:指定了要使用的模板引擎類帶點(diǎn)的Python路徑,Django默認(rèn)使用的是django.template.backends.django.DjangoTemplatesDIRS:一個目錄列表,指定模板文件的存放路徑。模板引擎將按照列表中定義的順序查找模板文件APP_DIRS:一個布爾值,如果為True時,模板引擎會在已安裝應(yīng)用的templates子目錄中查找模板OPTIONS:指定額外的選項,不同的模板引擎有著不同的可選額外參數(shù)模板系統(tǒng)語法模板變量與替換規(guī)則模板標(biāo)簽判斷執(zhí)行邏輯的if標(biāo)簽:與endif成對出現(xiàn),與Python中的if、elif類似字典查詢:{{a.b}}查詢a['b']屬性查詢:{{a.b}}查詢a.b方法調(diào)用:{{a.b}}查詢a.b()迭代序列元素的for標(biāo)簽:對列表或元組進(jìn)行迭代,與Python中的for語法類似獲取視圖訪問地址的url標(biāo)簽:與reverse函數(shù)類似,避免在模板中對訪問地址進(jìn)行硬編碼數(shù)字索引查詢:{{a.1}}查詢a[1]用于多行注釋的comment標(biāo)簽?zāi)0逑到y(tǒng)語法過濾器獲取變量長度的length過濾器轉(zhuǎn)換字符大小寫的過濾器:lower、upper獲取首個或末尾元素的過濾器:first、lasttruncatewords
過濾器截取指定個數(shù)的詞過濾器用于在顯示變量之前對變量的值進(jìn)行調(diào)整,它們在模板中非常常見,使用管道符號(“|”)指定。有些過濾器可以接受參數(shù),如果參數(shù)中帶有空格,需要用引號括起來。過濾器的特色是可以通過組合多個過濾器實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用。模板系統(tǒng)語法模板繼承一些高級語言都會有繼承的功能,將通用的功能或?qū)傩詫懺诟割悾ɑ蚧悾├锩?,子類繼承自父類,自動擁有父類的所有屬性和方法。同時,還可以通過重寫父類中的屬性和方法實(shí)現(xiàn)定制。這樣的繼承特性,通過抽象共性,減少了大量的重復(fù)代碼。
Django模板系統(tǒng)同樣支持繼承,這是一個非常有用的功能,在實(shí)際的項目開發(fā)中模板繼承也是非常常見的。一個簡單的父模板文件這個父模板文件中使用了{(lán)%block%}標(biāo)簽,也就是可以被子模板覆蓋的block。另外:block標(biāo)簽成對出現(xiàn),需要{%endblock%}標(biāo)記結(jié)束需要給block標(biāo)簽起個名字,子模板中具有同樣名稱的block塊完成對父模板的替換子模板可以不需要定義父模板中的所有block,此時,子模板將原樣使用父模板中的內(nèi)容子模板需要使用{%extends%}標(biāo)簽繼承父模板,且必須是模板中的第一個標(biāo)簽,通常繼承聲明會放在文件的第一行模板系統(tǒng)工作原理分析模板文件實(shí)現(xiàn)加載的過程_engine_list方法獲取模板后端:根據(jù)配置獲取模板后端實(shí)例DjangoTemplates加載模板文件:get_template方法模板渲染機(jī)制實(shí)現(xiàn)分析render方法:實(shí)現(xiàn)對模板的渲染,包括了變量替換、過濾器執(zhí)行等等。最終,render方法的返回就可以傳遞給HttpResponse作為視圖的響應(yīng)了。第8章Django表單系統(tǒng)使用表單系統(tǒng)實(shí)現(xiàn)表單表單系統(tǒng)的工作原理認(rèn)識表單認(rèn)識表單一個簡單的表單
在Web站點(diǎn)中與后端服務(wù)進(jìn)行交互,通常使用表單提交的方式。表單提交數(shù)據(jù)到達(dá)后端,首先要對數(shù)據(jù)做校驗(yàn),對于不合法的數(shù)據(jù)需要拒絕并提示給前端,通過校驗(yàn)之后才能執(zhí)行服務(wù)返回響應(yīng)。這就是常見的表單創(chuàng)建與處理流程。如果不使用Django的表單系統(tǒng),實(shí)現(xiàn)步驟可以大致總結(jié)為:創(chuàng)建模板文件用于提交表單數(shù)據(jù)顯示表單與對表單數(shù)據(jù)處理的業(yè)務(wù)邏輯但是實(shí)現(xiàn)這樣的表單,需要假設(shè)用戶熟悉這個功能,不會輸入錯誤。但是,實(shí)際情況是,用戶可能沒輸入查詢詞就點(diǎn)擊搜索按鈕,導(dǎo)致搜索結(jié)果出錯。同時,也沒有告知用戶問題出在了哪里。所以,這就暴露出當(dāng)前對表單的處理存在這樣的一些問題:表單頁面沒有錯誤提示視圖中缺少校驗(yàn)邏輯,即對用戶的輸入沒有做校驗(yàn),例如:是否為空、數(shù)據(jù)格式是否正確、類型是否滿足條件等等所以,自己實(shí)現(xiàn)一個可用的表單,需要創(chuàng)建表單模板,模板中包含需要提交給后端處理的數(shù)據(jù)以及對錯誤提示信息的顯示處理提交表單的視圖,視圖中包含對表單數(shù)據(jù)的校驗(yàn)和業(yè)務(wù)處理邏輯,當(dāng)表單數(shù)據(jù)不合法時,還需要給前端提示使用表單系統(tǒng)實(shí)現(xiàn)表單使用Form對象定義表單常用的表單字段類型實(shí)現(xiàn)對所有字段的驗(yàn)證:Form對象實(shí)例的is_valid方法根據(jù)字段定義生成HTML表單字段類型的基類Field常見的屬性字段requiredwidgetlabelinitialhelp_text……常用的表單字段類型CharFieldIntegerFieldBooleanFieldChoiceFieldEmailField……自定義表單字段類型:實(shí)現(xiàn)clean方法自定義表單的驗(yàn)證規(guī)則:以clean_開頭、字段名結(jié)尾的方法基于Model定制的表單表單系統(tǒng)的工作原理表單對象的創(chuàng)建過程Form:所有的表單對象都繼承自Form表單對象校驗(yàn)的實(shí)現(xiàn)過程is_valid方法:定義于BaseForm中,校驗(yàn)過程的實(shí)現(xiàn)就是is_valid方法的實(shí)現(xiàn)表單對象生成HTML的實(shí)現(xiàn)過程__str__方法:print打印對象實(shí)例,會調(diào)用__str__方法,其中調(diào)用了as_table方法ModelForm翻譯Model的實(shí)現(xiàn)過程第9章用戶認(rèn)證系統(tǒng)權(quán)限管理用戶認(rèn)證系統(tǒng)的應(yīng)用用戶與身份驗(yàn)證用戶與身份驗(yàn)證用戶與用戶組用戶認(rèn)證系統(tǒng)中定義了三個Model用來標(biāo)識用戶與用戶關(guān)系,分別是User(用戶)、AnonymousUser(匿名用戶)和Group(用戶組)。User對應(yīng)的數(shù)據(jù)表auth_userusername:用戶名,具有唯一性限制,最大長度為150個字符,只可以包含字母、數(shù)字、@、.、+、-、_這些字符password:密碼,Django并不會存儲原始密碼,存儲的實(shí)際是原始密碼經(jīng)過哈希處理之后的值is_active:布爾值,標(biāo)識當(dāng)前用戶是否處于激活狀態(tài),默認(rèn)值是Trueis_staff:布爾值,標(biāo)識用戶是否可以訪問管理后臺。默認(rèn)為False,即不可以is_superuser:布爾值,標(biāo)識是否是超級用戶,代表用戶擁有所有的權(quán)限。同樣,默認(rèn)值是False除了基礎(chǔ)屬性之外,User中還定義了與Group和Permission(權(quán)限)之間的關(guān)聯(lián)關(guān)系:groups=models.ManyToManyField(Group,...)user_permissions=models.ManyToManyField(Permission,...)用戶與身份驗(yàn)證用戶與用戶組
AnonymousUser是實(shí)現(xiàn)了User接口的類,它在業(yè)務(wù)代碼中很少被直接使用到。最常見的用法是對視圖的請求,對于未登錄用戶,request的user屬性即指向AnonymousUser。AnonymousUser定義
AnonymousUser定義了User的主要屬性,且都設(shè)置為“不可用”狀態(tài)。另外,對于set_password、check_password、delete、save方法,都直接拋出了NotImplementedError異常,并沒有對應(yīng)的實(shí)現(xiàn)。用戶與身份驗(yàn)證用戶與用戶組
Group標(biāo)識的是User的集合,屬于同一個用戶組的所有用戶具有“一些”相同的屬性。Group
Model定義Group只定義了一個基礎(chǔ)屬性字段:name,用于標(biāo)識組名。name被限制為最長80個字符,要求唯一性,但是對于字符內(nèi)容并沒有做要求。Group還定義了與Permission之間的關(guān)聯(lián)關(guān)系,所以,它還會有一張關(guān)聯(lián)表:auth_group_permissionsauth_group_permissions表結(jié)構(gòu)用戶組的概念主要有兩個作用:將一類用戶加入到一個用戶組中,方便對這一類用戶的統(tǒng)一操作。例如:發(fā)送郵件可以指定用戶組而不需要逐個添加用戶加入到某一個用戶組的用戶自動獲得當(dāng)前用戶組所擁有的權(quán)限用戶與身份驗(yàn)證用戶與用戶組根據(jù)給定的條件或?qū)傩試L試獲取用戶對象的行為被稱為用戶認(rèn)證。這也是非常常見的功能,為此,Django提供了authenticate方法用于對用戶身份進(jìn)行認(rèn)證??梢栽赟hell環(huán)境中簡單使用這個方法:在Shell中使用authenticate方法驗(yàn)證用戶身份
authenticate通常接受username與password作為參數(shù),如果通過認(rèn)證,則會返回User對象,否則,返回None。權(quán)限管理權(quán)限管理定義權(quán)限的數(shù)據(jù)表:Django利用Permission表定義權(quán)限Permission對應(yīng)的數(shù)據(jù)表auth_permissionPermission表的定義非常簡單,只有三個屬性:name:權(quán)限顯示的名稱,最多允許255個字符content_type:關(guān)聯(lián)ContentType(記錄app與model的信息)codename:權(quán)限的名稱編碼,最多允許100個字符給Model添加自定義的權(quán)限:Django也允許在定義Model時指定自定義的權(quán)限,只需要在Model的Meta中聲明即可。給Topic添加一個查看的權(quán)限permissions元選項中定義一個二元組,這個二元組的第一個元素指定了權(quán)限的codename,第二個元素指定了權(quán)限的name。注意:想要讓自定義的權(quán)限生效,需要再次執(zhí)行migrate操作,將修改同步到數(shù)據(jù)庫中權(quán)限管理權(quán)限管理權(quán)限的授予:添加、刪除以及清空權(quán)限權(quán)限獲取與校驗(yàn)的實(shí)現(xiàn)過程: User實(shí)例的get_all_permissions方法用于獲取用戶的權(quán)限; has_perm(s)方法用于校驗(yàn)用戶是否擁有對應(yīng)權(quán)限權(quán)限的授予對象可以是用戶,也可以是用戶組。如果是用戶組,則對組中的所有用戶生效。用戶與用戶組權(quán)限授予的方式:
用戶(利用User對象的user_permissions實(shí)現(xiàn)):user_permissions.set([…]):將當(dāng)前用戶的權(quán)限設(shè)置為指定的值user_permissions.add(…):在當(dāng)前用戶擁有權(quán)限的基礎(chǔ)上增加權(quán)限user_permissions.remove(…):刪除權(quán)限,它同樣可以接受多個值user_permissions.clear():清空用戶權(quán)限
用戶組(利用Group對象的permissions實(shí)現(xiàn)):permissions.set([…]):將當(dāng)前用戶組的權(quán)限設(shè)置為指定的值用戶認(rèn)證系統(tǒng)的應(yīng)用自定義認(rèn)證后端ModelBackend:Django指定了一個認(rèn)證后端,自定義認(rèn)證后端即實(shí)現(xiàn)了get_user和authenticate方法的Python類在模板中校驗(yàn)用戶身份和權(quán)限RequestContext:模板中傳遞的上下文,可以在模板中使用user和perms變量身份驗(yàn)證視圖使用裝飾器限制對視圖的訪問@login_required:驗(yàn)證用戶是否登錄,只有登錄的用戶才可以訪問視圖@permission_required:校驗(yàn)用戶是否具有特定的權(quán)限,只有校驗(yàn)通過的用戶才可以訪問視圖第10章Django路由系統(tǒng)路由系統(tǒng)工作原理路由系統(tǒng)基礎(chǔ)路由系統(tǒng)基礎(chǔ)認(rèn)識URLconfURLconf:是一套模式,定義了URL與視圖函數(shù)之間的映射表,實(shí)現(xiàn)了將不同的URL分發(fā)給不同的視圖處理函數(shù)URL模式定義相關(guān)的函數(shù)path函數(shù):用于定義URL模式re_path函數(shù):同樣用于定義URL模式,但是定義的是正則表達(dá)式路由include函數(shù):將URLconf的完整Python路徑引入到另一個URLconf中register_converter函數(shù):用于注冊path函數(shù)中route參數(shù)用到的轉(zhuǎn)換器路由參數(shù)傳遞無參數(shù)傳遞URL模式參數(shù)綁定請求傳參動態(tài)路由參數(shù)捕獲自定義錯誤頁面修改系統(tǒng)配置定義錯誤頁面模板文件定義錯誤處理視圖配置handler路由系統(tǒng)工作原理偏函數(shù)partial:在函數(shù)調(diào)用之前,預(yù)先固定參數(shù),降低函數(shù)調(diào)用的難度實(shí)現(xiàn)路由分發(fā)的include函數(shù)path函數(shù)的工作原理_path函數(shù):path和re_path都指向了_path函數(shù),只是給定了不同的Pattern參數(shù)。所以,它們的工作原理基本是一致的HTTP請求查找視圖的實(shí)現(xiàn)過程_get_response:HTTP請求到來之后,會交給BaseHandler的get_response方法處理。get_response中對HTTP請求的處理又會調(diào)用到_get_response方法,也就是在這里實(shí)現(xiàn)了視圖函數(shù)的匹配過程第11章Django中間件Django內(nèi)置的中間件中間件的工作原理中間件基礎(chǔ)中間件基礎(chǔ)中間件簡介什么是中間件:中間件用于在視圖函數(shù)執(zhí)行之前和執(zhí)行之后做一些預(yù)處理和后處理操作,功能類似于裝飾器。它的表現(xiàn)形式是一個Python類,類中定義了固定名稱的方法,即鉤子函數(shù)。Django框架會對每一個HTTP請求在特定的時機(jī)執(zhí)行這些鉤子函數(shù)。中間件包含5個(不一定是每個中間件都有)鉤子函數(shù):process_requestprocess_viewprocess_exceptionprocess_template_responseprocess_response中間件的鉤子函數(shù)process_request:請求預(yù)處理函數(shù),接受HttpRequest對象實(shí)例process_view:視圖預(yù)處理函數(shù),在確定了當(dāng)前請求對應(yīng)的視圖函數(shù)之后被調(diào)用process_exception:異常后處理函數(shù),當(dāng)視圖函數(shù)拋出了未捕獲的異常時被調(diào)用process_template_response:TemplateResponse或響應(yīng)實(shí)例有render方法的后處理函數(shù)。在視圖函數(shù)執(zhí)行之后被調(diào)用process_response:響應(yīng)后處理函數(shù),Django執(zhí)行了視圖函數(shù)并生成響應(yīng)之后被調(diào)用中間件基礎(chǔ)自定義中間件自定義中間件是很簡單的,最直接的方法是繼承自django.utils.deprecation.MiddlewareMixin,并選擇實(shí)現(xiàn)適合的鉤子函數(shù)。需要注意,Django要求中間件必須要至少包含一個鉤子函數(shù),但即使是沒有實(shí)現(xiàn)任何一個函數(shù),嘗試加載這個類也并不會報錯,只是沒有意義。通常會將中間件定義在middleware.py文件中,但也不是強(qiáng)制要求。自定義中間件FirstMiddleware自定義中間件SecondMiddleware需要知道:實(shí)現(xiàn)三個鉤子函數(shù):process_request、process_view和process_response。其中,讓前兩個函數(shù)返回None,以保證會執(zhí)行視圖函數(shù)。中間件在MIDDLEWARE列表中定義的順序會影響它們的執(zhí)行順序Django內(nèi)置的中間件會話中間件SessionMiddlewareSessionMiddleware定義于django.contrib.sessions
應(yīng)用:定義了django_session表用于記錄會話SESSION_ENGINE
變量:可以在項目的配置文件(settings.py)中指定SESSION_ENGINE變量,默認(rèn)情況下,它并沒有被顯示的指定。此時,Django則會使用框架內(nèi)的定義。這個變量指定了存儲會話數(shù)據(jù)的模塊,命名為SessionStore。默認(rèn)的配置指定使用數(shù)據(jù)庫去保存會話數(shù)據(jù)。SessionMiddleware的實(shí)現(xiàn)原理: process_request:函數(shù)最核心的實(shí)現(xiàn)就是給HttpRequest實(shí)例添加了session屬性 process_response:主要完成兩個工作,保存會話數(shù)據(jù)和給瀏覽器設(shè)置Cookie會話是為了解決HTTP協(xié)議無狀態(tài)的問題,不用每次打開Web站點(diǎn)都需要重新登錄。Django使用Cookie來保持會話,默認(rèn)情況下,會話信息保存到數(shù)據(jù)庫中。這就是會話中間件SessionMiddleware實(shí)現(xiàn)的功能。django_session表結(jié)構(gòu)django_session中定義了三個字段,字段含義分別是:session_key:主鍵,所以是惟一的,記錄的值是放置在Cookie中的會話idsession_data:存放序列化之后的會話數(shù)據(jù)字符串expire_date:過期時間,標(biāo)識會話狀態(tài)是否失效Django內(nèi)置的中間件身份認(rèn)證中間件AuthenticationMiddleware
依賴關(guān)系:AuthenticationMiddleware相比SessionMiddleware要簡單許多,且它們之間存在著依賴關(guān)系。AuthenticationMiddleware依賴于SessionMiddleware中間件。AuthenticationMiddleware實(shí)現(xiàn)源碼AuthenticationMiddleware
只定義了process_request函數(shù),負(fù)責(zé)給HttpRequest對象添加user屬性添加user屬性之前,它會斷言當(dāng)前的HttpRequest有session屬性,這也是SessionMiddleware必須在“前面”定義的原因注意:settings.py文件中的MIDDLEWARE變量不僅定義了系統(tǒng)中裝載的中間件,而且還指示了中間件執(zhí)行的順序。所以,對于存在依賴關(guān)系的中間件,位置不能隨意調(diào)動。中間件的工作原理責(zé)任鏈設(shè)計模式責(zé)任鏈模式是一種對象的行為模式。多個對象組成處理鏈條,每一個對象都保持對下一個對象的引用。請求在這個鏈條上傳遞,直到符合要求被鏈上的某一個對象處理。由于發(fā)出請求的客戶端并不需要知道是鏈上的哪一個對象處理了它,所以,系統(tǒng)可以在不通知客戶端的情況下重新組織,變更對象之間的職責(zé)關(guān)系。有這樣一個需求:根據(jù)分?jǐn)?shù)(score)進(jìn)行評級,比如:90分到100分之間的是A、75分到90分之間的是B等等。此時,就可以實(shí)現(xiàn)一些處理對象,將它們組成鏈,score在遇到合適的條件時返回處理結(jié)果。抽象類,構(gòu)造處理鏈條的入口與處理方法的定義set_successor方法用來設(shè)定下一個處理對象的引用,以此來形成鏈條。handle方法是處理邏輯的具體實(shí)現(xiàn)。定義處理對象(HandleA、HandleB、HandleC),它們都需要繼承自AbstractHandle,并實(shí)現(xiàn)handle方法處理鏈條即為:HandleA
->
HandleB
->
HandleC中間件的工作原理中間件基類MiddlewareMixinMiddlewareMixin實(shí)現(xiàn)源碼初始化方法接受一個可選的參數(shù)get_response,作為當(dāng)前對象的一個屬性。__call__是Python的魔術(shù)方法,當(dāng)類對象實(shí)現(xiàn)了這個方法,它就可以像函數(shù)一樣被調(diào)用。所以,繼承自MiddlewareMixin的中間件可以通過傳遞request參數(shù)調(diào)用。
MiddlewareMixin的核心實(shí)現(xiàn)就是__call__方法,它定義了鉤子函數(shù)的調(diào)用規(guī)則:如果定義了process_request,則會調(diào)用,并將返回賦值給response如果process_request沒有返回,調(diào)用初始化時傳遞進(jìn)來的get_response,并將返回賦值給response如果定義了process_response,調(diào)用它,并獲取返回對于一個中間件來說,process_request與process_response方法之間執(zhí)行的是其他的中間件和視圖函數(shù)。所以,可以知道,__call__方法中的get_response實(shí)現(xiàn)了這一過程。中間件的工作原理中間件的裝載與執(zhí)行中間件的裝載過程:發(fā)生在初始化WSGIHandler實(shí)例的過程中中間件的執(zhí)行過程:請求到來之后,BaseHandler的get_response會被調(diào)用,中間件鏈就會對請求進(jìn)行處理第12章Django信號機(jī)制信號的工作原理信號的概念與應(yīng)用信號的概念與應(yīng)用信號的基礎(chǔ)概念信號包含三要素:
發(fā)送者:信號的發(fā)出方,即誰發(fā)送了信號
信號:發(fā)送的信號本身
接收者:信號的接收者,即信號是發(fā)給誰的
Django中的信號用于在框架執(zhí)行操作時解耦。它的基本思想就是當(dāng)系統(tǒng)中的某個狀態(tài)發(fā)生改變時,通過信號通知其他對這個狀態(tài)感興趣的系統(tǒng)去更新狀態(tài)。信號接收者其實(shí)就是一個簡單的回調(diào)函數(shù),將這個函數(shù)注冊到信號上,當(dāng)特定的事件發(fā)生時,發(fā)送者發(fā)送信號,回調(diào)函數(shù)被執(zhí)行。需要注意,這里回調(diào)函數(shù)的執(zhí)行是同步的,所以,需要異步執(zhí)行的耗時任務(wù)不能作為信號的接收者。信號的概念與應(yīng)用信號的基礎(chǔ)概念信號的應(yīng)用場景:事件發(fā)生或完成的通知、事件發(fā)生之后的清理或初始化內(nèi)置的信號:所有的信號都是Signal的實(shí)例,Signal中除初始化函數(shù)外定義了4個操作信號的重要方法。下面,依次對它們進(jìn)行介紹:初始化函數(shù):def__init__(self,providing_args=None,use_caching=False)
providing_args:可選的列表類型,其中每一個元素都是字符串,標(biāo)識信號提供給接收者的參數(shù)
use_caching:默認(rèn)值是False,如果設(shè)置為True,則緩存會被設(shè)置為弱引用將回調(diào)函數(shù)注冊到信號上:defconnect(self,receiver,sender=None,weak=True,dispatch_uid=None)
receiver:必須要指定的回調(diào)函數(shù),信號發(fā)送后,就會執(zhí)行到這個函數(shù)
sender:信號的發(fā)送者,可以不提供
weak:默認(rèn)值是True,代表以弱引用的方式存儲信號處理器
dispatch_uid:用于指定receiver的唯一標(biāo)識符,以防止信號多次發(fā)送的情況發(fā)送信號:defsend(self,sender,**named)
sender:標(biāo)識信號的發(fā)送者,大多數(shù)情況下它是一個類對象
**named:用來指定任意數(shù)量的關(guān)鍵字參數(shù),這些參數(shù)將會傳遞給receiver斷開信號:defdisconnect(self,receiver=None,sender=None,dispatch_uid=None)
receiver:標(biāo)識需要斷開已注冊的信號接收者,如果使用了dispatch_uid去標(biāo)識receiver,這個參數(shù)可以是None
sender:已注冊的信號發(fā)送者
dispatch_uid:receiver的唯一標(biāo)識符信號的概念與應(yīng)用信號的基礎(chǔ)概念內(nèi)置的信號:Django內(nèi)置了很多信號,且它們可以按照發(fā)送者分為很多類。Model相關(guān)的信號
django.db.models.signals.pre_init與django.db.models.signals.post_init:實(shí)例化模型之前與之后發(fā)送的信號,即在__init__方法執(zhí)行的前后
django.db.models.signals.pre_save與django.db.models.signals.post_save:模型實(shí)例保存(執(zhí)行save方法)前后發(fā)送的信號
django.db.models.signals.pre_delete與django.db.models.signals.post_delete:模型實(shí)例或QuerySet的delete方法執(zhí)行前后發(fā)送的信號
django.db.models.signals.m2m_changed:模型實(shí)例中
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年劇本殺運(yùn)營公司綠色運(yùn)營推廣管理制度
- 2025年生態(tài)濕地公園建設(shè)可行性分析:技術(shù)創(chuàng)新與生態(tài)濕地修復(fù)
- 農(nóng)業(yè)病蟲害防控智能化趨勢:2025年監(jiān)測預(yù)警系統(tǒng)可行性報告
- 2026年生物科技行業(yè)創(chuàng)新報告及基因編輯技術(shù)臨床應(yīng)用
- 2025年跨境電商獨(dú)立站品牌忠誠度培養(yǎng)報告
- 2025年新能源汽車五年市場報告
- 生態(tài)養(yǎng)殖循環(huán)產(chǎn)業(yè)鏈建設(shè)項目2025年技術(shù)創(chuàng)新與農(nóng)業(yè)產(chǎn)業(yè)鏈優(yōu)化可行性研究
- 冷鏈物流配送路徑優(yōu)化系統(tǒng)開發(fā)可行性研究報告-2025年行業(yè)挑戰(zhàn)與對策
- 介休教師面試題目及答案
- 前列腺相關(guān)問題解答與護(hù)理
- 2026年酒店住宿預(yù)訂合同
- 選舉法知識課件
- 2026云南省產(chǎn)品質(zhì)量監(jiān)督檢驗(yàn)研究院招聘編制外人員2人筆試備考題庫及答案解析
- 2026年1月浙江省高考首考選考地理試卷試題(含答案)
- 人教版PEP五年級英語上冊“閱讀理解”專項練習(xí)(含答案)
- 中學(xué)生網(wǎng)絡(luò)社交行為調(diào)查報告
- 2025-2026學(xué)年大象版小學(xué)科學(xué)五年級上冊期末復(fù)習(xí)卷及答案
- 精益工程師考試試題及答案2
- 道路清掃保潔服務(wù)方案投標(biāo)文件(技術(shù)方案)
- 2025年牛肉醬行業(yè)分析報告及未來發(fā)展趨勢預(yù)測
- 2024腦動靜脈畸形多學(xué)科診療專家共識
評論
0/150
提交評論