對於web開發者來說,socket是基礎。因為Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。
對於真實開發中的python web程序來說,一般會分為兩部分:服務器程序和應用程序。
服務器程序負責對socket服務器進行封裝,並在請求到來時,對請求的各種數據進行整理。
應用程序則負責具體的邏輯處理。
為了方便應用程序的開發,就出現了眾多的Web框架,例如:Django、Flask、tornado 等。
框架,即framework,特指為解決一個開放性問題而設計的具有一定約束性的支撐結構,使用框架可以幫你快速開發特定的系統。
框架多了,開發方式也就多了,支持不同框架的服務器程序不可能也要多起來,就需要標准化。
在Python中,WSGI(Web Server Gateway Interface)定義了Web服務器與Web應用(或Web框架)之間的標准接口。在WSGI的規范下,各種各樣的Web服務器和Web框架都可以很好的交互。
python標准庫提供的獨立WSGI服務器稱為wsgiref。
from wsgiref.simple_server import make_server def app(environ, start_response): status = '200 OK' # HTTP Status headers = [('Content-type', 'text/plain')] # HTTP Headers start_response(status, headers) # The returned object is going to be printed return ["Hello World"] httpd = make_server('', 8000, hello_world_app) print "Serving on port 8000..." # Serve until process is killed httpd.serve_forever()
#每個WSGI應用程序必須有一個應用程序對象 - 一個可接受兩個參數的可調用對象。 為此,將使用一個函數(請注意,您不限於一個函數,您可以使用一個類)。
#傳遞給函數的第一個參數是包含CGI樣式環境變量的字典,第二個變量是可調用對象。
整個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。
1 from wsgiref.simple_server import make_server 2 import time 3 4 def f1(req): 5 print(req) 6 print(req["QUERY_STRING"]) 7 f1=open("index1.html","rb") 8 data1=f1.read() 9 return [data1] 10 11 def f2(req): 12 f2=open("index2.html","rb") 13 data2=f2.read() 14 return [data2] 15 16 def routers(): 17 urlpatterns = ( 18 ('/index1',f1), 19 ('/index2',f2), 20 ) 21 return urlpatterns 22 23 def application(environ, start_response): 24 print(environ['PATH_INFO']) 25 path=environ['PATH_INFO'] 26 start_response('200 OK', [('Content-Type', 'text/html')]) 27 28 urlpatterns = routers() 29 func = None 30 for item in urlpatterns: 31 if item[0] == path: 32 func = item[1] 33 break 34 if func: 35 return func(environ) 36 else: 37 return ["<h1>404</h1>".encode("utf8")] 38 httpd = make_server('', 8518, application) 39 print('Serving HTTP on port 8518...') 40 # 開始監聽HTTP請求: 41 httpd.serve_forever()
MVC和MTV模式
著名的MVC模式:MVC就是把web應用分為模型(M),控制器(C),視圖(V)三層;可以使業務邏輯與數據表現分開;他們之間以一種插件似的,松耦合的方式連接在一起。

模型負責業務對象與數據庫的對象(ORM),視圖負責與用戶的交互(頁面),控制器(C)接受用戶的輸入調用模型和視圖完成用戶的請求。
Django的MTV模式本質上與MVC模式沒有什么差別,也是各組件之間為了保持松耦合關系,只是定義上有些許不同,Django的MTV分別代表:
Model(模型):負責業務對象與數據庫的對象,使用的是(ORM對象關系映射, Object Relational Mapping),我們所能控制的就是models.py文件,負責數據庫管理
Template(模版):負責如何把頁面展示給用戶,Template層負責怎么樣顯示數據,利用一些格式化的html文件,使數據按照要求顯示(顯示在哪里,怎么顯示等等;需要在工程目錄下,建立templates文件夾,然后在setting.py中設置好templates目錄的路徑。然后在此目錄中建立所需html文件。 。
View(視圖):負責業務邏輯,並在適當的時候調用Model和Template,django中的view層是用於控制要顯示什么數據,我們能看到的就是views.py文件,views.py(可以是任意名字)
此外,Django還有一個url分發器,它的作用是將一個個URL的頁面請求分發給不同的view處理,view再調用相應的Model和Template


Django部署:
terminal創建一個項目 django-admin.py startproject mysite 創建一個app python manage.py startapp blog 配置setting.py文件,注冊app INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'djcelery', ‘’blog’, ) 配置數據庫 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'root', 'PASSWORD': '123456', 'HOST': 'localhost', 'PORT': '3460', } } 啟動開發服務器(更換端口) python manage.py runserver 8090 創建視圖 views.py from django.http import HttpResponse def hello(request): return HttpResponse("Hello world") URLconf 配置 from django.conf.urls.defaults import patterns, include, url from blog.views import hello urlpatterns = patterns('', url(r'^hello/$', hello), )



步驟1:瀏覽器首先向服務器發送HTTP請求,請求包括:
方法:GET還是POST,GET僅請求資源,POST會附帶用戶數據;
如果是POST,那么請求還包括一個Body,包含用戶數據。
步驟2:服務器向瀏覽器返回HTTP響應,響應包括:
響應代碼:200表示成功,3xx表示重定向,4xx表示客戶端發送的請求有錯誤,5xx表示服務器端處理時發生了錯誤;
響應類型:由Content-Type指定;以及其他相關的Header;通常服務器的HTTP響應會攜帶內容,也就是有一個Body,包含響應的內容,網頁的HTML源碼就在Body中。
步驟3:如果瀏覽器還需要繼續向服務器請求其他資源,比如圖片,就再次發出HTTP請求,重復步驟1、2。
Django的過程

Web服務器收到一個http請求;Django把web服務器傳過來的請求轉換成一個請求對象;
Django在URLconf里查找正確的視圖函數;
調用這個視圖函數,參數為請求對象以及任何捕捉到的URL參數;
然后視圖會創建並返回一個響應對象;
Django將這個響應對象轉換成web服務器可以理解的格式;
Web服務器將響應發送給客戶端。
