web框架(web framework)或者叫作web應用框架(web application framework),是用於進行web開發的一套軟件架構。大多數的web框架提供了一套開發和部署網站的方式。爲web的行爲提供了一套支持支持的方法。使用web框架,不少的業務邏輯外的功能不須要本身再去完善,而是使用框架已有的功能就能夠。html
web框架使得在進行web應用開發的時候,減小了工做量。web框架主要用於動態網絡開發,動態網絡主要是指如今的主要的頁面,能夠實現數據的交互和業務功能的完善。使用web框架進行web開發的時候,在進行數據緩存、數據庫訪問、數據安全校驗等方面,不須要本身再從新實現,而是將業務邏輯相關的代碼寫入框架就能夠。也就是說,經過對web框架進行主觀上的「縫縫補補」,就能夠實現本身進行web開發的需求了。前端
目前Python主流的框架有Django和Flask等。Django是一個比較重量級的框架,重量級的意思是說,Django幾乎全部的功能都幫助開發者寫好了,有時候若是想作一個簡單的網站,並不須要太多功能,這時候使用Django的話,就比較不合適,由於在部署網站的時候會致使不少沒必要要的功能也部署了進來。而Flask是一個輕量級的框架,一些核心的功能實現了,可是實現的功能並無Django那麼多,這樣能夠進行本身的發揮,在Flask的基礎上,若是想實現更多的功能,能夠很方便地加入。python
Java目前的主流開發框架是ssm(spring spring-mvc和mybatis)。相比以前的ssh(spring struts hibernate),ssm也是比較輕量級的框架。mysql
web框架是用來進行web應用開發的一個軟件架構。主要用於動態網絡開發。開發者在基於web框架實現本身的業務邏輯。web框架實現了不少功能,爲實現業務邏輯提供了一套通用方法。web
MySQL:在web數據庫中使用pymysql模塊建立一個表格,並在該表格中插入數據,這裏咱們直接在MySQL裏面插入的數據----models.py文件spring
後端:建立一個web服務器,實現可以對/login和/auth路徑的判斷並返回正確的數據---manage.py文件sql
前端:瀏覽器數據庫
準備的相應文件login.html後端
(1)準備的文件login.html瀏覽器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://127.0.0.1:8000/auth" method="post"> 用戶名:<input type="text" name="user"> 密碼:<input type="password" name="pwd"> <input type="submit"> </form> </body> </html>
(2)python用於建立MySQL的表的文件models.py
1 # -*- coding:utf-8 -*- 2 # 做用:在數據庫中建立表,運行程序生成表結構,這裏咱們直接在MySQL上插入了數據 3 # id | name | password | 4 # +----+------+----------+ 5 # | 1 | lilz | 123 6 7 import pymysql 8 #鏈接數據庫 9 conn = pymysql.connect(host='127.0.0.1',port= 3306,user = 'root',passwd='123',db='web') #db:庫名 10 #建立遊標 11 cur = conn.cursor() 12 13 sql=''' 14 create table userinfo( 15 id INT PRIMARY KEY , 16 name VARCHAR(32) , 17 password VARCHAR(32) 18 ) 19 20 ''' 21 cur.execute(sql) 22 23 #提交 24 conn.commit() 25 #關閉指針對象 26 cur.close() 27 #關閉鏈接對象 28 conn.close()
(3)python的web服務器的文件manage.py
1 # 這個模塊封裝了socketserver 2 from wsgiref.simple_server import make_server 3 # 這是個爬蟲模塊,這裏咱們用做解開獲取到請求體中的數據 4 from urllib.parse import parse_qs 5 # python與數據庫交互的模塊 6 import pymysql 7 8 9 def application(environ, start_response): 10 ''' 11 根據路徑的不一樣返回不一樣的數據 12 :param environ: 表示服務端接收到的請求信息---字典 13 # environ裏的PATH_INFO表示請求的路徑,獲取路徑的方法:environ.get("PATH_INFO") 14 :param start_response:封裝響應格式的 15 :return: 16 ''' 17 # 獲取請求路徑 18 print('environ',environ) 19 path=environ.get("PATH_INFO") 20 data = b'404!' 21 if path == '/login': 22 with open('login.html','rb')as f: 23 data = f.read() 24 elif path=='/auth': 25 # 登錄認證 26 # 1.獲取用戶輸入的用戶名和密碼 27 # 1.1獲取請求體的長度 28 request_body_size = int(environ.get('CONTENT_LENGTH', 0)) 29 # 1.2 30 # 能夠從請求數據environ中看到'wsgi.input': < _io.BufferedReader name = 832 >是閱讀器對象,數據都在這個對象裏 31 # 所以下面的read就是讀取數據的長度 32 request_body = environ['wsgi.input'].read(request_body_size) 33 # 數據 34 print('=====>',request_body) #=====> b'user=lilz&pwd=123' 35 36 request_data = parse_qs(request_body) 37 print('=====>', request_data) #{b'user': [b'lilz'], b'pwd': [b'123']} 38 user = (request_data.get(b'user')[0]).decode('utf8') 39 pwd = (request_data.get(b'pwd')[0]).decode('utf8') 40 print('=====>', user,pwd) # lilz 123 41 42 43 #2.去數據庫作校驗,查看用戶,密碼是否合法,使用pymysql 44 # 鏈接數據庫 45 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='web') # db:庫名 46 # 建立遊標 47 cur = conn.cursor() 48 49 sql = "select * from userinfo where name = '%s'and password= '%s'" % (user, pwd) 50 51 cur.execute(sql) 52 # cur.fetchone()若是獲取成功,就有值 53 if cur.fetchone(): 54 # 驗證成功 55 data = "登錄成功".encode('gbk') 56 else: 57 # 驗證失敗 58 data = "登錄失敗".encode('gbk') 59 #3.響應返回 60 # 封包 61 # 響應行、響應頭 62 start_response('200 OK', [('Content-Type', 'text/html')]) 63 # 響應體 64 return [data] 65 66 67 httpd = make_server('127.0.0.1', 8000, application) 68 69 print('Serving HTTP on port 8000...') 70 # 開始監聽HTTP請求: 71 # (啓動:等待客戶端鏈接--->一旦鏈接成功就會回調到make_server參數裏的application函數) 72 httpd.serve_forever()
咱們該怎麼優化呢?首先咱們代碼的缺陷就是隻有兩個路徑,若是加一個路徑咱們又得一個elif,因此咱們用函數封住代碼
1 # -*- coding:utf-8 -*- 2 # 這個模塊封裝了socketserver 3 from wsgiref.simple_server import make_server 4 # 這是個爬蟲模塊,這裏咱們用做解開獲取到請求體中的數據 5 from urllib.parse import parse_qs 6 # python與數據庫交互的模塊 7 import pymysql 8 9 10 # 視圖函數:處理http請求的函數 11 def login(environ): 12 with open('login.html', 'rb')as f: 13 data = f.read() 14 return data 15 def auth(environ): 16 # 登錄認證 17 # 1.獲取用戶輸入的用戶名和密碼 18 # 1.1獲取請求體的長度 19 request_body_size = int(environ.get('CONTENT_LENGTH', 0)) 20 # 1.2 21 # 能夠從請求數據environ中看到'wsgi.input': < _io.BufferedReader name = 832 >是閱讀器對象,數據都在這個對象裏 22 # 所以下面的read就是讀取數據的長度 23 request_body = environ['wsgi.input'].read(request_body_size) 24 # 數據 25 print('=====>', request_body) # =====> b'user=lilz&pwd=123' 26 27 request_data = parse_qs(request_body) 28 print('=====>', request_data) # {b'user': [b'lilz'], b'pwd': [b'123']} 29 user = (request_data.get(b'user')[0]).decode('utf8') 30 pwd = (request_data.get(b'pwd')[0]).decode('utf8') 31 print('=====>', user, pwd) # lilz 123 32 33 # 2.去數據庫作校驗,查看用戶,密碼是否合法,使用pymysql 34 # 鏈接數據庫 35 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='web') # db:庫名 36 # 建立遊標 37 cur = conn.cursor() 38 39 sql = "select * from userinfo where name = '%s'and password= '%s'" % (user, pwd) 40 41 cur.execute(sql) 42 # cur.fetchone()若是獲取成功,就有值 43 if cur.fetchone(): 44 # 驗證成功 45 data = "登錄成功".encode('gbk') 46 else: 47 # 驗證失敗 48 data = "登錄失敗".encode('gbk') 49 50 return data 51 52 53 def application(environ, start_response): 54 ''' 55 根據路徑的不一樣返回不一樣的數據 56 :param environ: 表示服務端接收到的請求信息---字典 57 # environ裏的PATH_INFO表示請求的路徑,獲取路徑的方法:environ.get("PATH_INFO") 58 :param start_response:封裝響應格式的 59 :return: 60 ''' 61 # 獲取請求路徑 62 print('environ',environ) 63 path=environ.get("PATH_INFO") 64 data = b'404!' 65 if path == '/login': 66 data=login(environ) 67 elif path=='/auth': 68 data=auth(environ) 69 70 #3.響應返回 71 # 封包 72 # 響應行、響應頭 73 start_response('200 OK', [('Content-Type', 'text/html')]) 74 # 響應體 75 return [data] 76 77 78 httpd = make_server('127.0.0.1', 8000, application) 79 80 print('Serving HTTP on port 8000...') 81 # 開始監聽HTTP請求: 82 # (啓動:等待客戶端鏈接--->一旦鏈接成功就會回調到make_server參數裏的application函數) 83 httpd.serve_forever()
再次優化時,咱們能夠把視圖函數單獨存放在一個文件中views.py
咱們把判斷路徑的if語句換成循環,能夠把全部的路徑放在一個列表裏這樣遍歷列表,找到和請求中的路徑同樣的,而後再調用該路徑函數
1 # -*- coding:utf-8 -*- 2 # 這個模塊封裝了socketserver 3 from wsgiref.simple_server import make_server 4 from views import login,auth,fav 5 # python與數據庫交互的模塊 6 import pymysql 7 8 9 def application(environ, start_response): 10 ''' 11 根據路徑的不一樣返回不一樣的數據 12 :param environ: 表示服務端接收到的請求信息---字典 13 # environ裏的PATH_INFO表示請求的路徑,獲取路徑的方法:environ.get("PATH_INFO") 14 :param start_response:封裝響應格式的 15 :return: 16 ''' 17 # 獲取請求路徑 18 print('environ',environ) 19 path=environ.get("PATH_INFO") 20 21 # url與視圖函數的映射關係 22 urlpattens = [ 23 ('/login',login), 24 ('/auth',auth), 25 ('/favicon.ico',fav) #圖標請求,常常覆蓋其餘的請求,這個請求是圖標,迴應數據時不會把別的覆蓋掉 26 ] 27 28 func=None 29 # 遍歷url與視圖函數的映射關係列表,若是有和請求消息中路徑相等的咱們把該路徑對應的視圖函數取出來賦給func,而後調用視圖函數 30 for item in urlpattens: 31 if item[0]==path: 32 func=item[1] 33 break 34 func = None 35 for item in urlpattens: 36 print("------>", item[0]) 37 if item[0] == path: 38 func = item[1] 39 break 40 if not func: 41 data = b"<h1>404</h1>" 42 else: 43 data = func(environ) 44 45 #3.響應返回 46 # 封包 47 # 響應行、響應頭 48 start_response('200 OK', [('Content-Type', 'text/html')]) 49 # 響應體 50 return [data] 51 52 53 httpd = make_server('127.0.0.1', 8000, application) 54 55 print('Serving HTTP on port 8000...') 56 # 開始監聽HTTP請求: 57 # (啓動:等待客戶端鏈接--->一旦鏈接成功就會回調到make_server參數裏的application函數) 58 httpd.serve_forever()
注意圖標請求的影響,代碼裏面有作處理。這裏準備了一張favicon.ico的標題圖標文件,本身下載放到項目目錄中
1 # -*- coding:utf-8 -*- 2 # 這是個爬蟲模塊,這裏咱們用做解開獲取到請求體中的數據 3 from urllib.parse import parse_qs 4 import pymysql 5 6 7 # 視圖函數:處理http請求的函數 8 def login(environ): 9 with open('login.html', 'rb')as f: 10 data = f.read() 11 return data 12 def auth(environ): 13 # 登錄認證 14 # 1.獲取用戶輸入的用戶名和密碼 15 # 1.1獲取請求體的長度 16 request_body_size = int(environ.get('CONTENT_LENGTH', 0)) 17 # 1.2 18 # 能夠從請求數據environ中看到'wsgi.input': < _io.BufferedReader name = 832 >是閱讀器對象,數據都在這個對象裏 19 # 所以下面的read就是讀取數據的長度 20 request_body = environ['wsgi.input'].read(request_body_size) 21 # 數據 22 print('=====>', request_body) # =====> b'user=lilz&pwd=123' 23 24 request_data = parse_qs(request_body) 25 print('=====>', request_data) # {b'user': [b'lilz'], b'pwd': [b'123']} 26 user = (request_data.get(b'user')[0]).decode('utf8') 27 pwd = (request_data.get(b'pwd')[0]).decode('utf8') 28 print('=====>', user, pwd) # lilz 123 29 30 # 2.去數據庫作校驗,查看用戶,密碼是否合法,使用pymysql 31 # 鏈接數據庫 32 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='web') # db:庫名 33 # 建立遊標 34 cur = conn.cursor() 35 36 sql = "select * from userinfo where name = '%s'and password= '%s'" % (user, pwd) 37 38 cur.execute(sql) 39 # cur.fetchone()若是獲取成功,就有值 40 if cur.fetchone(): 41 # 驗證成功 42 data = "登錄成功".encode('gbk') 43 else: 44 # 驗證失敗 45 data = "登錄失敗".encode('gbk') 46 47 return data 48 49 def fav(environ): 50 with open("favicon.ico",'rb')as f: 51 data = f.read() 52 return data
把url與視圖函數的對應關係的列表單獨放在一個文件中---url.py
1 # -*- coding:utf-8 -*- 2 # 這個模塊封裝了socketserver 3 from wsgiref.simple_server import make_server 4 from url import urlpattens 5 # python與數據庫交互的模塊 6 import pymysql 7 8 9 def application(environ, start_response): 10 ''' 11 根據路徑的不一樣返回不一樣的數據 12 :param environ: 表示服務端接收到的請求信息---字典 13 # environ裏的PATH_INFO表示請求的路徑,獲取路徑的方法:environ.get("PATH_INFO") 14 :param start_response:封裝響應格式的 15 :return: 16 ''' 17 # 獲取請求路徑 18 print('environ',environ) 19 path=environ.get("PATH_INFO") 20 21 22 23 func=None 24 # 遍歷url與視圖函數的映射關係列表,若是有和請求消息中路徑相等的咱們把該路徑對應的視圖函數取出來賦給func,而後調用視圖函數 25 for item in urlpattens: 26 if item[0]==path: 27 func=item[1] 28 break 29 func = None 30 for item in urlpattens: 31 print("------>", item[0]) 32 if item[0] == path: 33 func = item[1] 34 break 35 if not func: 36 data = b"<h1>404</h1>" 37 else: 38 data = func(environ) 39 40 #3.響應返回 41 # 封包 42 # 響應行、響應頭 43 start_response('200 OK', [('Content-Type', 'text/html')]) 44 # 響應體 45 return [data] 46 47 48 httpd = make_server('127.0.0.1', 8000, application) 49 50 print('Serving HTTP on port 8000...') 51 # 開始監聽HTTP請求: 52 # (啓動:等待客戶端鏈接--->一旦鏈接成功就會回調到make_server參數裏的application函數) 53 httpd.serve_forever()
1 # -*- coding:utf-8 -*- 2 # 這是個爬蟲模塊,這裏咱們用做解開獲取到請求體中的數據 3 from urllib.parse import parse_qs 4 import pymysql 5 6 7 # 視圖函數:處理http請求的函數 8 def login(environ): 9 with open('login.html', 'rb')as f: 10 data = f.read() 11 return data 12 def auth(environ): 13 # 登錄認證 14 # 1.獲取用戶輸入的用戶名和密碼 15 # 1.1獲取請求體的長度 16 request_body_size = int(environ.get('CONTENT_LENGTH', 0)) 17 # 1.2 18 # 能夠從請求數據environ中看到'wsgi.input': < _io.BufferedReader name = 832 >是閱讀器對象,數據都在這個對象裏 19 # 所以下面的read就是讀取數據的長度 20 request_body = environ['wsgi.input'].read(request_body_size) 21 # 數據 22 print('=====>', request_body) # =====> b'user=lilz&pwd=123' 23 24 request_data = parse_qs(request_body) 25 print('=====>', request_data) # {b'user': [b'lilz'], b'pwd': [b'123']} 26 user = (request_data.get(b'user')[0]).decode('utf8') 27 pwd = (request_data.get(b'pwd')[0]).decode('utf8') 28 print('=====>', user, pwd) # lilz 123 29 30 # 2.去數據庫作校驗,查看用戶,密碼是否合法,使用pymysql 31 # 鏈接數據庫 32 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='web') # db:庫名 33 # 建立遊標 34 cur = conn.cursor() 35 36 sql = "select * from userinfo where name = '%s'and password= '%s'" % (user, pwd) 37 38 cur.execute(sql) 39 # cur.fetchone()若是獲取成功,就有值 40 if cur.fetchone(): 41 # 驗證成功 42 data = "登錄成功".encode('gbk') 43 else: 44 # 驗證失敗 45 data = "登錄失敗".encode('gbk') 46 47 return data 48 49 def fav(environ): 50 with open("favicon.ico",'rb')as f: 51 data = f.read() 52 return data
1 from views import login,auth,fav 2 3 # url與視圖函數的映射關係 4 urlpattens = [ 5 ('/login', login), 6 ('/auth', auth), 7 ('/favicon.ico', fav) # 圖標請求,常常覆蓋其餘的請求,這個請求是圖標,迴應數據時不會把別的覆蓋掉 8 ]
這些文件都放一塊,很差,咱們分好目錄
templates:放全部的html文件、圖標
這樣須要修改一下路徑
總結:
templates:放全部的html文件、圖標
manage.py:啓動文件(總邏輯)
models.py:與數據庫交互的文件
url.py:url與視圖函數的對應關係的列表---關係映射
views.py:視圖函數----邏輯
1 # -*- coding:utf-8 -*- 2 # 這個模塊封裝了socketserver 3 from wsgiref.simple_server import make_server 4 from url import urlpattens 5 # python與數據庫交互的模塊 6 import pymysql 7 8 9 def application(environ, start_response): 10 ''' 11 根據路徑的不一樣返回不一樣的數據 12 :param environ: 表示服務端接收到的請求信息---字典 13 # environ裏的PATH_INFO表示請求的路徑,獲取路徑的方法:environ.get("PATH_INFO") 14 :param start_response:封裝響應格式的 15 :return: 16 ''' 17 # 獲取請求路徑 18 print('environ',environ) 19 path=environ.get("PATH_INFO") 20 21 22 23 func=None 24 # 遍歷url與視圖函數的映射關係列表,若是有和請求消息中路徑相等的咱們把該路徑對應的視圖函數取出來賦給func,而後調用視圖函數 25 for item in urlpattens: 26 if item[0]==path: 27 func=item[1] 28 break 29 func = None 30 for item in urlpattens: 31 print("------>", item[0]) 32 if item[0] == path: 33 func = item[1] 34 break 35 if not func: 36 data = b"<h1>404</h1>" 37 else: 38 data = func(environ) 39 40 #3.響應返回 41 # 封包 42 # 響應行、響應頭 43 start_response('200 OK', [('Content-Type', 'text/html')]) 44 # 響應體 45 return [data] 46 47 48 httpd = make_server('127.0.0.1', 8000, application) 49 50 print('Serving HTTP on port 8000...') 51 # 開始監聽HTTP請求: 52 # (啓動:等待客戶端鏈接--->一旦鏈接成功就會回調到make_server參數裏的application函數) 53 httpd.serve_forever()
1 from views import login,auth,fav 2 3 # url與視圖函數的映射關係 4 urlpattens = [ 5 ('/login', login), 6 ('/auth', auth), 7 ('/favicon.ico', fav) # 圖標請求,常常覆蓋其餘的請求,這個請求是圖標,迴應數據時不會把別的覆蓋掉 8 ]
1 # -*- coding:utf-8 -*- 2 # 這是個爬蟲模塊,這裏咱們用做解開獲取到請求體中的數據 3 from urllib.parse import parse_qs 4 import pymysql 5 6 7 # 視圖函數:處理http請求的函數 8 def login(environ): 9 with open('templates/login.html', 'rb')as f: 10 data = f.read() 11 return data 12 def auth(environ): 13 # 登錄認證 14 # 1.獲取用戶輸入的用戶名和密碼 15 # 1.1獲取請求體的長度 16 request_body_size = int(environ.get('CONTENT_LENGTH', 0)) 17 # 1.2 18 # 能夠從請求數據environ中看到'wsgi.input': < _io.BufferedReader name = 832 >是閱讀器對象,數據都在這個對象裏 19 # 所以下面的read就是讀取數據的長度 20 request_body = environ['wsgi.input'].read(request_body_size) 21 # 數據 22 print('=====>', request_body) # =====> b'user=lilz&pwd=123' 23 24 request_data = parse_qs(request_body) 25 print('=====>', request_data) # {b'user': [b'lilz'], b'pwd': [b'123']} 26 user = (request_data.get(b'user')[0]).decode('utf8') 27 pwd = (request_data.get(b'pwd')[0]).decode('utf8') 28 print('=====>', user, pwd) # lilz 123 29 30 # 2.去數據庫作校驗,查看用戶,密碼是否合法,使用pymysql 31 # 鏈接數據庫 32 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='web') # db:庫名 33 # 建立遊標 34 cur = conn.cursor() 35 36 sql = "select * from userinfo where name = '%s'and password= '%s'" % (user, pwd) 37 38 cur.execute(sql) 39 # cur.fetchone()若是獲取成功,就有值 40 if cur.fetchone(): 41 # 驗證成功 42 data = "登錄成功".encode('gbk') 43 else: 44 # 驗證失敗 45 data = "登錄失敗".encode('gbk') 46 47 return data 48 49 def fav(environ): 50 with open("templates/favicon.ico",'rb')as f: 51 data = f.read() 52 return data
1 # -*- coding:utf-8 -*- 2 # 做用:在數據庫中建立表,運行程序生成表結構,這裏咱們直接在MySQL上插入了數據 3 # id | name | password | 4 # +----+------+----------+ 5 # | 1 | lilz | 123 6 7 import pymysql 8 #鏈接數據庫 9 conn = pymysql.connect(host='127.0.0.1',port= 3306,user = 'root',passwd='123',db='web') #db:庫名 10 #建立遊標 11 cur = conn.cursor() 12 13 sql=''' 14 create table userinfo( 15 id INT PRIMARY KEY , 16 name VARCHAR(32) , 17 password VARCHAR(32) 18 ) 19 20 ''' 21 cur.execute(sql) 22 23 #提交 24 conn.commit() 25 #關閉指針對象 26 cur.close() 27 #關閉鏈接對象 28 conn.close()
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 9 <form action="http://127.0.0.1:8000/auth" method="post"> 10 用戶名:<input type="text" name="user"> 11 密碼:<input type="password" name="pwd"> 12 <input type="submit"> 13 </form> 14 </body> 15 </html>
若是你想訪問一個本身寫的網頁,第一,準備好html文件放在templates目錄中,再url.py上列表中添加url與視圖函數的對應關係;
第二,在views.py中添加視圖函數。
M:mdoel 與數據庫打交道
C:controller 控制器(url的分發與視圖函數的邏輯處理)
V:View 視圖 (html文件,即用戶界面)
Web服務器開發領域裏著名的MVC模式,所謂MVC就是把Web應用分爲模型(M),控制器(C)和視圖(V)三層,他們之間以一種插件式的、鬆耦合的方式鏈接在一塊兒,模型負責業務對象與數據庫的映射(ORM),視圖負責與用戶的交互(頁面),控制器接受用戶的輸入調用模型和視圖完成用戶的請求。這樣強制性的使應用程序輸入、處理和輸出分開。
模型、視圖、控制器的分離,使得一個模型能夠有多種視圖。若是用戶經過某個視圖的控制器改變了模型的數據,全部其餘依賴於這些數據的視圖都反映出這些變化。所以,不管什麼時候發生了何種數據變化,控制器都會將變化通知給全部的視圖,致使數據的更新。這就是一種模型的變化的傳播機制。
Django的MTV模式本質上和MVC是同樣的,也是爲了各組件間保持鬆耦合關係,只是定義上有些許不一樣,Django的MTV分別是值:
除了以上三層以外,還須要一個URL分發器,它的做用是將一個個URL的頁面請求分發給不一樣的View處理,View再調用相應的Model和Template,MTV的響應模式以下所示
通常是用戶經過瀏覽器向咱們的服務器發起一個請求(request),這個請求回去訪問視圖函數,(若是不涉及到數據調用,那麼這個時候視圖函數返回一個模板也就是一個網頁給用戶),視圖函數調用模型,模型去數據庫查找數據,而後逐級返回,視圖函數把返回的數據填充到模板中空格中,最後返回網頁給用戶。