初識Django
一、什麽是web框架?
框架,即framework,特制為解決一個開放性問題而設計的具有一定約束性的支撐結構,使用框架可以幫你快速開發特定的系統。
對於所有的web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。
import socket def handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8")) client.sennd("<h1 style=‘color:red‘>Hello,yuan</h1>".encode(‘utf8‘)) def main(): sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) socket.bind((‘localhost‘,8001)) sock.listen(5) while True: connection,address = sock.accept() handle_request(connection) connection.close() if __name__ == ‘__main__‘: main()
最簡單的Web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,接受用戶請求,從文件中讀取HTML,返回。
如果要動態生成HTML,就需要把上述步驟自己來實現,不過,接受HTTP請求,解析HTTP請求,發送HTTP響應都是苦力活,如果我們自己來寫這些底層代碼,還沒開始寫動態HTML就得花個把月去讀HTTP規範。
正確的做法是底層代碼由專門的服務器軟件實現,我們用Python專註於生成HTML文檔。因為我們不希望接觸到TCP連接,HTTP原始請求和響應格式,所以需要一個統一的接口,讓我們專心用Python編寫Web業務。
這個接口就是WSGI: Web Server Gateway InterFace。
-----------------------------Do a web framework ourselves---------------------------
from wsgiref.simple_server import make_server def application(environ, start_response): start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)]) return [b‘<h1>Hello, web!</h1>‘] httpd = make_server(‘‘, 8080, application) print(‘Serving HTTP on port 8000...‘) # 開始監聽HTTP請求: httpd.serve_forever()
註意:
整個application()函數本身沒有涉及到任何解析HTTP的部分,也就是說,底層代碼不需要我們自己編寫, 我們只負責在更高層次上考慮如何響應請求就可以了。 application()函數必須由WSGI服務器來調用。有很多符合WSGI規範的服務器,我們可以挑選一個來用。 Python內置了一個WSGI服務器,這個模塊叫wsgiref application()函數就是符合WSGI標準的一個HTTP處理函數,它接收兩個參數: //environ:一個包含所有HTTP請求信息的dict對象; //start_response:一個發送HTTP響應的函數。 在application()函數中,調用: start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)]) 就發送了HTTP響應的Header,註意Header只能發送一次,也就是只能調用一次start_response()函數。 start_response()函數接收兩個參數,一個是HTTP響應碼,一個是一組list表示的HTTP Header,每 個Header用一個包含兩個str的tuple表示。 通常情況下,都應該把Content-Type頭發送給瀏覽器。其他很多常用的HTTP Header也應該發送。 然後,函數的返回值b‘<h1>Hello, web!</h1>‘將作為HTTP響應的Body發送給瀏覽器。 有了WSGI,我們關心的就是如何從environ這個dict對象拿到HTTP請求信息,然後構造HTML, 通過start_response()發送Header,最後返回Body。
print(environ[‘PATH_INFO‘]) path=environ[‘PATH_INFO‘] start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)]) f1=open("index1.html","rb") data1=f1.read() f2=open("index2.html","rb") data2=f2.read() if path=="/yuan": return [data1] elif path=="/alex": return [data2] else: return ["<h1>404</h1>".encode(‘utf8‘)]
from wsgiref.simple_server import make_server def f1(): f1=open("index1.html","rb") data1=f1.read() return [data1] def f2(): f2=open("index2.html","rb") data2=f2.read() return [data2] def application(environ, start_response): print(environ[‘PATH_INFO‘]) path=environ[‘PATH_INFO‘] start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)]) if path=="/yuan": return f1() elif path=="/alex": return f2() else: return ["<h1>404</h1>".encode("utf8")] httpd = make_server(‘‘, 8502, application) print(‘Serving HTTP on port 8084...‘) # 開始監聽HTTP請求: httpd.serve_forever()
from wsgiref.simple_server import make_server def f1(req): print(req) print(req["QUERY_STRING"]) f1=open("index1.html","rb") data1=f1.read() return [data1] def f2(req): f2=open("index2.html","rb") data2=f2.read() return [data2] import time def f3(req): #模版以及數據庫 f3=open("index3.html","rb") data3=f3.read() times=time.strftime("%Y-%m-%d %X", time.localtime()) data3=str(data3,"utf8").replace("!time!",str(times)) return [data3.encode("utf8")] def routers(): urlpatterns = ( (‘/yuan‘,f1), (‘/alex‘,f2), ("/cur_time",f3) ) return urlpatterns def application(environ, start_response): print(environ[‘PATH_INFO‘]) path=environ[‘PATH_INFO‘] start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)]) urlpatterns = routers() func = None for item in urlpatterns: if item[0] == path: func = item[1] break if func: return func(environ) else: return ["<h1>404</h1>".encode("utf8")] httpd = make_server(‘‘, 8518, application) print(‘Serving HTTP on port 8084...‘) # 開始監聽HTTP請求: httpd.serve_forever()
二 MVC和MTV模式
著名的MVC模式:所謂MVC就是把web應用分為模型(M),控制器(C),視圖(V)三層;他們之間以一種插件似的,松耦合的方式連接在一起。
模型負責業務對象與數據庫的對象(ORM),視圖負責與用戶的交互(頁面),控制器(C)接受用戶的輸入調用模型和視圖完成用戶的請求。
Django的MTV模式本質上與MVC模式沒有什麽差別,也是各組件之間為了保持松耦合關系,只是定義上有些許不同,Django的MTV分別代表:
Model(模型):負責業務對象與數據庫的對象(ORM)
Template(模版):負責如何把頁面展示給用戶
View(視圖):負責業務邏輯,並在適當的時候調用Model和Template
此外,Django還有一個url分發器,它的作用是將一個個URL的頁面請求分發給不同的view處理,view再調用相應的Model和Template
初識Django