一、概要
Django(維基百科) Django是一個(gè)開(kāi)放源代碼的Web應(yīng)用框架,由Python寫(xiě)成。采用了MVC的軟件設(shè)計(jì)模式,即模型M,視圖V和控制器C。它最初是被開(kāi)發(fā)來(lái)用于管理勞倫斯出版集團(tuán)旗下的一些以新聞內(nèi)容為主的網(wǎng)站的。并于2005年7月在BSD許可證下發(fā)布。這套框架是以比利時(shí)的吉普賽爵士吉他手Django Reinhardt來(lái)命名的。
Django的主要目標(biāo)是使得開(kāi)發(fā)復(fù)雜的、數(shù)據(jù)庫(kù)驅(qū)動(dòng)的網(wǎng)站變得簡(jiǎn)單。Django注重組件的重用性和“可插拔性”,敏捷開(kāi)發(fā)和DRY法則(Don't Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和數(shù)據(jù)模型。
Django 于 2008年6月17日正式成立基金會(huì)。
Django吸引人的特點(diǎn)
在Python各種web框架中,Django的文檔最完善、市場(chǎng)占有率最高、招聘職位最多!
二、特點(diǎn)
- Django是走大而全的方向,它最出名的是其全自動(dòng)化的管理后臺(tái):只需要使用起ORM,做簡(jiǎn)單的對(duì)象定義,它就能自動(dòng)生成數(shù)據(jù)庫(kù)結(jié)構(gòu)、以及全功能的管理后臺(tái)。
- Django內(nèi)置的ORM跟框架內(nèi)的其他模塊耦合程度高。應(yīng)用程序必須使用Django內(nèi)置的ORM,否則就不能享受到框架內(nèi)提供的種種基于其ORM的便利;理論上可以切換掉其ORM模塊,但這就相當(dāng)于要把裝修完畢的房子拆除重新裝修,倒不如一開(kāi)始就去毛胚房做全新的裝修。
- Django的賣(mài)點(diǎn)是超高的開(kāi)發(fā)效率,其性能擴(kuò)展有限;采用Django的項(xiàng)目,在流量達(dá)到一定規(guī)模后,都需要對(duì)其進(jìn)行重構(gòu),才能滿(mǎn)足性能的要求。
- Django適用的是中小型的網(wǎng)站,或者是作為大型網(wǎng)站快速實(shí)現(xiàn)產(chǎn)品雛形的工具。
- Django模板的設(shè)計(jì)哲學(xué)是徹底的將代碼、樣式分離; Django從根本上杜絕在模板中進(jìn)行編碼、處理數(shù)據(jù)的可能。
三 Django 、Flask、Tornado的對(duì)比
- Django是大而全的方向,開(kāi)發(fā)效率高。它的MTV框架,自帶的ORM,admin后臺(tái)管理,自帶的sqlite數(shù)據(jù)庫(kù)和開(kāi)發(fā)測(cè)試用的服務(wù)器 給開(kāi)發(fā)者提高了超高的開(kāi)發(fā)效率
- Flask是輕量級(jí)的框架,自由,靈活,可擴(kuò)展性很強(qiáng),核心基于Werkzeug WSGI工具和jinja2模板引擎
- Tornado走的是少而精的方向,性能優(yōu)越。它最出名的是異步非阻塞的設(shè)計(jì)方式,Tornado的兩大核心模塊:
- iostraem:對(duì)非阻塞式的socket進(jìn)行簡(jiǎn)單的封裝,
- ioloop:對(duì)I/O多路復(fù)用的封裝,它實(shí)現(xiàn)了一個(gè)單例
四、Django版本介紹
1、Django對(duì)Python版本的依賴(lài)關(guān)系
| Django 版本 | Python 版本 |
|---|---|
| 1.8 | 2.7, 3.2 (until the end of 2016), 3.3, 3.4, 3.5 |
| 1.9, 1.10 | 2.7, 3.4, 3.5 |
| 1.11 | 2.7, 3.4, 3.5, 3.6 |
| 2.0 | 3.4, 3.5, 3.6 |
| 2.1 | 3.5, 3.6, 3.7 |
2、Django版本支持路線(xiàn)圖
?
三、什么是WSGI
1、WSGI
首先我們來(lái)寫(xiě)一段通過(guò)編寫(xiě)標(biāo)準(zhǔn)的WSGI程序
from wsgiref.simple_server import make_server def wsgi_app(environ, start_response): # 調(diào)用服務(wù)器程序提供的 start_response,填入兩個(gè)參數(shù) 狀態(tài)碼 跟返回頭部的信息 start_response('200 OK', [('Content-Type', 'text/html')]) db= pymysql.connect(host="localhost",user="root", password="root",db="test",port=3306) cur = db.cursor() sql = "select name,password from user where id=1" result = cur.fetchone() # 必須返回可迭代對(duì)象,并指定編碼 text = r'<h1>' + result[0] + '</h1>' return [.encode('utf8')] if __name__ == '__main__': # 創(chuàng)建一個(gè)服務(wù)器,IP127.0.0.1,端口是8000,處理函數(shù)是application httpd = make_server('127.0.0.1', 8000, wsgi_app) # 監(jiān)聽(tīng)HTTP請(qǐng)求: httpd.serve_forever()通過(guò)上面的代碼我們發(fā)現(xiàn)傳統(tǒng)的WSG編程有一下幾個(gè)不足
- 應(yīng)用中有多處需要連接數(shù)據(jù)庫(kù)會(huì)怎樣呢? 每個(gè)獨(dú)立的WSG腳本,不應(yīng)該重復(fù)寫(xiě)數(shù)據(jù)庫(kù)連接的代碼。 比較實(shí)用的辦法是寫(xiě)一個(gè)共享函數(shù),可被多個(gè)代碼調(diào)用。
- 一個(gè)開(kāi)發(fā)人員 確實(shí) 需要去關(guān)注如何輸出Content-Type以及完成所有操作后去關(guān)閉數(shù)據(jù)庫(kù)么? 此類(lèi)問(wèn)題只會(huì)降低開(kāi)發(fā)人員的工作效率,增加犯錯(cuò)誤的幾率。 那些初始化和釋放 相關(guān)的工作應(yīng)該交給一些通用的框架來(lái)完成。
- 如果這樣的代碼被重用到一個(gè)復(fù)合的環(huán)境中會(huì)發(fā)生什么? 每個(gè)頁(yè)面都分別對(duì)應(yīng)獨(dú)立的數(shù)據(jù)庫(kù)和密碼嗎?
- 如果一個(gè)Web設(shè)計(jì)師,完全沒(méi)有Python開(kāi)發(fā)經(jīng)驗(yàn),但是又需要重新設(shè)計(jì)頁(yè)面的話(huà),又將發(fā)生什么呢? 一個(gè)字符寫(xiě)錯(cuò)了,可能導(dǎo)致整個(gè)應(yīng)用崩潰。 理想的情況是,頁(yè)面顯示的邏輯與從數(shù)據(jù)庫(kù)中讀取記錄分隔開(kāi),這樣 Web設(shè)計(jì)師的重新設(shè)計(jì)不會(huì)影響到之前的業(yè)務(wù)邏輯(可跳過(guò)直接看四MVC設(shè)計(jì)模式)
2、WSGI介紹
- 概要
WSGI (Python Web Server Gateway Interface, Python Web服務(wù)器網(wǎng)關(guān)接口)是一個(gè)Web服務(wù)器和Web應(yīng)用程序之間的標(biāo)準(zhǔn)化接口,用于增進(jìn)應(yīng)用程序在不同的Web服務(wù)器和框架之間的可移植性。關(guān)于該標(biāo)準(zhǔn)的官方說(shuō)明可以參考PEP333。 - WSGI規(guī)范如下:
服務(wù)器的請(qǐng)求處理程序中要調(diào)用符合WSGI規(guī)范的網(wǎng)關(guān)接口;
網(wǎng)關(guān)接口調(diào)用應(yīng)用程序,并且要定義start_response(status, headers)函數(shù),用于返回響應(yīng);
應(yīng)用程序中實(shí)現(xiàn)一個(gè)函數(shù)或者一個(gè)可調(diào)用對(duì)象webapp(environ, start_response)。其中environ是環(huán)境設(shè)置的字典,由服務(wù)器和WSGI網(wǎng)關(guān)接口設(shè)置,start_response是由網(wǎng)關(guān)接口定義的函數(shù)。
3、uwsgi
- 說(shuō)明
與WSGI一樣是一種通信協(xié)議,是uWSGI服務(wù)器的獨(dú)占協(xié)議,用于定義傳輸信息的類(lèi)型(type of information),每一個(gè)uwsgi packet前4byte為傳輸信息類(lèi)型的描述,與WSGI協(xié)議是兩種東西,據(jù)說(shuō)該協(xié)議是fcgi協(xié)議的10倍快。
4、uWSGI
- 說(shuō)明
是一個(gè)web服務(wù)器,實(shí)現(xiàn)了WSGI協(xié)議、uwsgi協(xié)議、http協(xié)議等
5、Django框架分析WSGI
1、WSGI
- django WSGI application
class WSGIHandler(base.BaseHandler): initLock = Lock() request_class = WSGIRequest def __call__(self, environ, start_response): # 1.加載中間件 if self._request_middleware is None: ... # 2. 處理請(qǐng)求 request = self.request_class(environ) # 3. 處理響應(yīng) response = self.get_response(request) # 設(shè)置響應(yīng)頭部 response_headers = [(str(k), str(v)) for k, v in response.items()] for c in response.cookies.values(): response_headers.append((str('Set-Cookie'), str(c.output(header='')))) # 4. server提供的回調(diào)方法,將響應(yīng)的header和status返回給server start_response(force_str(status), response_headers) if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'): response = environ['wsgi.file_wrapper'](response.file_to_stream) return response - 說(shuō)明
- 加載所有中間件,以及執(zhí)行框架相關(guān)的操作,設(shè)置當(dāng)前線(xiàn)程腳本前綴,發(fā)送請(qǐng)求開(kāi)始信號(hào);
- 處理請(qǐng)求,調(diào)用get_response()方法處理當(dāng)前請(qǐng)求,該方法的的主要邏輯是通過(guò)urlconf找到對(duì)應(yīng)的view和callback,按順序執(zhí)行各種middleware和callback。
- 調(diào)用由server傳入的start_response()方法將響應(yīng)header與status返回給server。返回響應(yīng)正文
2、WSGI Server
- 作用
負(fù)責(zé)獲取http請(qǐng)求,將請(qǐng)求傳遞給WSGI application,由application處理請(qǐng)求后返回response。以Django內(nèi)建server為例看一下具體實(shí)現(xiàn)。通過(guò)runserver運(yùn)行django 項(xiàng)目,在啟動(dòng)時(shí)都會(huì)調(diào)用下面的run方法,創(chuàng)建一個(gè)WSGIServer的實(shí)例,之后再調(diào)用其serve_forever()方法啟動(dòng)服務(wù) - 源碼
def run(addr, port, wsgi_handler, ipv6=False, threading=False): server_address = (addr, port) if threading: httpd_cls = type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {}) else: httpd_cls = WSGIServer # 這里的wsgi_handler就是WSGIApplication httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6) if threading: httpd.daemon_threads = True httpd.set_app(wsgi_handler) httpd.serve_forever()
四、MVC設(shè)計(jì)模式
1、說(shuō)明
MVC 是一種使用 MVC(Model View Controller 模型-視圖-控制器)Web 應(yīng)用程序的軟件設(shè)計(jì)模式
框架模式是指針對(duì)于某一特定領(lǐng)域,可以適用于各種應(yīng)用的模式,即為專(zhuān)用領(lǐng)域提供通用的或現(xiàn)成的基礎(chǔ)結(jié)構(gòu),以獲得最高級(jí)別的重用性
最高級(jí)別,那么比它更低級(jí)別的還有什么?
軟件生產(chǎn)中有三種級(jí)別的重用:
內(nèi)部重用,即在同一應(yīng)用中能公共使用的抽象塊;
代碼重用,即將通用模塊組合成庫(kù)或工具集,以便在多個(gè)應(yīng)用和領(lǐng)域都能使用;
應(yīng)用框架的重用,即為專(zhuān)用領(lǐng)域提供通用的或現(xiàn)成的基礎(chǔ)結(jié)構(gòu),以獲得最高級(jí)別的重用性。
2、模型(Model)
- 說(shuō)明
管理應(yīng)用程序的狀態(tài)(通常是數(shù)據(jù)庫(kù)操作),并約束改變狀態(tài)的行為(或者叫做“業(yè)務(wù)規(guī)則”)。 - 作用
是應(yīng)用程序中用于處理應(yīng)用程序數(shù)據(jù)邏輯的部分。通常模型對(duì)象主要封裝對(duì)數(shù)據(jù)庫(kù)層的訪問(wèn),對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行增、刪、改、查操作,
3、視圖(View)
- 說(shuō)明
顯示數(shù)據(jù)(數(shù)據(jù)庫(kù)記錄) - 作用
是應(yīng)用程序中處理數(shù)據(jù)顯示的部分。通常視圖是依據(jù)模型數(shù)據(jù)創(chuàng)建的前端網(wǎng)頁(yè)。生成頁(yè)面展示的html內(nèi)容。
4、控制器(Controller)
- 說(shuō)明
處理輸入輸出 - 作用
是應(yīng)用程序中處理用戶(hù)交互的部分。接受外部用戶(hù)的操作,根據(jù)操作訪問(wèn)模型獲取數(shù)據(jù),并調(diào)用“視圖”顯示這些數(shù)據(jù)??刂破魇菍ⅰ澳P汀焙汀耙晥D”隔離,并成為二者之間的聯(lián)系紐帶
5、交互示例圖
-
示例圖
image - 說(shuō)明
- 用戶(hù)首先在界面中進(jìn)行人機(jī)交互,例如在瀏覽器地址欄輸入地址
- 然后請(qǐng)求發(fā)送到控制器,控制器根據(jù)請(qǐng)求類(lèi)型和請(qǐng)求的指令發(fā)送到相應(yīng)的模型,
- 模型可以與數(shù)據(jù)庫(kù)進(jìn)行交互,進(jìn)行增刪改查操作
- 完成之后,根據(jù)業(yè)務(wù)的邏輯選擇相應(yīng)的視圖進(jìn)行顯示,
- 此時(shí)用戶(hù)獲得此次交互的反饋信息,用戶(hù)可以進(jìn)行下一步交互,如此循環(huán)
6、MVC的特性
- 耦合性低:
利用MVC可以實(shí)現(xiàn)視圖層和控制層分離,允許視圖層與控制層的分離開(kāi)發(fā),允許更改視圖層代碼而不用重新編譯模型和控制器代碼;模型是自包含的,并且與控制器和視圖相分離,所以很容易進(jìn)行數(shù)據(jù)庫(kù)的遷移 - 重用性高:
對(duì)于不同網(wǎng)站和應(yīng)用,由于視圖層、控制層和模型層的低耦合性,同一模塊代碼往往可以重復(fù)使用
決定了MVC在大型網(wǎng)站開(kāi)發(fā)和多人協(xié)作時(shí)的代碼的易集成和可維護(hù),這也是當(dāng)今MVC較為流行的原因。 - 能使網(wǎng)站程序結(jié)構(gòu)更合理
當(dāng)我們?nèi)ラ_(kāi)發(fā)網(wǎng)站的時(shí)候,最笨的方法,你可能把每個(gè)頁(yè)面建成一個(gè)python文件。如果你的網(wǎng)站只有兩三個(gè)頁(yè)面,那你可以不用MVC,但我們做一般的網(wǎng)站的時(shí)候,動(dòng)輒幾十個(gè)頁(yè)面,把所有頁(yè)面放在一個(gè)文件中顯然不是我們所能接受的,于是你需要一個(gè)合理的思想去將你的代碼分類(lèi),按功能把他們分成不同的目錄,且由程序智能的載入調(diào)用,這就是MVC要幫助你做的 - 有利于團(tuán)隊(duì)開(kāi)發(fā)
在開(kāi)發(fā)過(guò)程中,可以更好的分工,更好的協(xié)作。有利于開(kāi)發(fā)出高質(zhì)量的軟件。良好的項(xiàng) 目架構(gòu)設(shè)計(jì),將減少編碼工作量
五、Django框架MTV
1、說(shuō)明
Django的MTV模式本質(zhì)上和MVC是一樣的,也是為了各組件間保持松耦合關(guān)系,只是定義上有些許不同,
Django 里更關(guān)注的是模型(Model)、模板(Template)和視圖(Views), Django 也被稱(chēng)為 MTV 框架 。
2、模型(Model)
- 說(shuō)明
即模型層,即數(shù)據(jù)存取層。 該層處理與數(shù)據(jù)相關(guān)的所有事務(wù): 如存取、如何驗(yàn)證有效
3、模板(Template)
- 說(shuō)明
即表現(xiàn)層。 該層處理與表現(xiàn)相關(guān)的決定: 如何在頁(yè)面或其他類(lèi)型文檔中進(jìn)行顯示。
4、視圖(View)
- 說(shuō)明
即控制層(業(yè)務(wù)邏輯層)。 該層包含存取模型及調(diào)取恰當(dāng)模板的相關(guān)邏輯。 你可以把它看作模型與模板之間的橋梁。
5、交互示意圖
-
示例圖
image - 說(shuō)明
- 瀏覽器發(fā)送請(qǐng)求(基本上是字節(jié)類(lèi)型的字符串)到web服務(wù)器。
- web服務(wù)器(比如,Nginx)把這個(gè)請(qǐng)求轉(zhuǎn)交到一個(gè)WSGI(比如,uWSGI),或者直接地文件系統(tǒng)能夠取出一個(gè)文件(比如,一個(gè)CSS文件)。
- 不像web服務(wù)器那樣,WSGI服務(wù)器可以直接運(yùn)行Python應(yīng)用。請(qǐng)求生成一個(gè)被稱(chēng)為environ的Ptyhon字典,而且,可以選擇傳遞過(guò)去幾個(gè)中間件的層,最終,達(dá)到Django應(yīng)用。
- URLconf中含有屬于應(yīng)用的urls.py選擇一個(gè)視圖處理基于請(qǐng)求的URL的那個(gè)請(qǐng)求,這個(gè)請(qǐng)求就已經(jīng)變成了HttpRequest——一個(gè)Python字典對(duì)象。
- 被選擇的那個(gè)視圖通常要做下面所列出的一件或者更多件事情
- 通過(guò)模型與數(shù)據(jù)庫(kù)對(duì)話(huà)。
- 使用模板渲染HTML或者任何格式化過(guò)的響應(yīng)。
- 返回一個(gè)純文本響應(yīng)(不被顯示的)。
- 拋出一個(gè)異常。
- HttpResponse對(duì)象離開(kāi)Django后,被渲染為一個(gè)字符串。
- 在瀏覽器見(jiàn)到一個(gè)美化的,渲染后的web頁(yè)面
六、Django整體結(jié)構(gòu)圖


