Django 14天從小白到進階- Day1 Django 初識 摘自 金角大王 https://www.cnblogs.com/alex3714/articles/8662706.html
本節內容
Http原理介紹
自行開發一個Web框架
WSGI介紹
Django介紹
MVC/MTV
Django安裝
建立專案與APP
開發第一個頁面
為什麼學Django?
Good question , 知Python者必知Django, 因為這可是Python語言裡最流行&強大的Web框架,同時亦是全球第5大WEB框架,可快速構建穩定強大的WEB專案,大大提高開發效率,很多知名專案都是基於Django開發,如Disqus、Pinterest、Instagram、Bitbucket等, Django官方Slogan是The framework for perfectionist with deadline! 一個為完美主義者且又開發工期很緊的人設計的框架,事實確實如此,Django自身集成了豐富的WEB開發通用元件,如使用者認證、分頁、中介軟體、快取、session等,可以避免浪費大量時間重複造輪子。
Http原理介紹
HTTP協議(HyperText Transfer Protocol,超文字傳輸協議)是用於從WWW伺服器傳輸超文字到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網路傳輸減少。它不僅保證計算機正確快速地傳輸超文字文件,還確定傳輸文件中的哪一部分,以及哪部分內容首先顯示(如文字先於圖形)等。
HTTP協議通常承載於TCP協議之上,有時也承載於TLS或SSL協議層之上,這個時候,就成了我們常說的HTTPS。如下圖所示:
HTTP協議永遠都是客戶端發起請求,伺服器回送響應。見下圖:
這個Client和Server端本質上是一個Socket客戶端和伺服器端,Http協議可以說是基於Socket的再上層封裝。
HTTP特性
基於TCP/IP協議
你每次開啟百度或其它網站,都需要先建立好TCP/IP會話,當然這個瀏覽器會幫你做了。
短連線
你開啟 https://www.luffycity.com/ 或其它網站, 當伺服器端把這個頁面的內容全返回後,就把這次連線斷開了,會話就結束了,你在瀏覽器上看到頁面內容已經是下載到本地的了,所以此時如果伺服器端更新了內容,你本地的頁面自然是不會跟著變的。除非你再重新整理一下,這樣就又進行了一次會話。那為何是短連線呢?你想一想
被動響應
這個很好理解,你不請求百度,百度是不會主動連線你的。
無狀態
無狀態是指,當瀏覽器傳送請求給伺服器的時候,伺服器響應,但是同一個瀏覽器再發送請求給伺服器的時候,他會響應,但是他不知道你就是剛才那個瀏覽器,簡單地說,就是伺服器不會去記得你,所以是無狀態協議。
自行開發一個Web Server
既然Http協議本質上是基於Socket做的,我們又學過Socket了,那能不能自己開發一個Web Server呢? 回答是of course.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# -*- coding:utf-8 -*-
# created by Alex Li - 路飛學城
import socket
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
sock.bind(( 'localhost' , 8000 ))
sock.listen( 5 )
while True :
# 等待瀏覽器訪問
conn, addr = sock.accept()
# 接收瀏覽器傳送來的請求內容
data = conn.recv( 1024 )
print (data)
# 給瀏覽器返回內容
conn.send(b "HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n" )
conn.send( "電腦前的你長的真好看!" .encode( "utf-8" ))
# 關閉和瀏覽器建立的socket連線
conn.close()
if __name__ = = "__main__" :
main()
|
我靠,這麼簡單,是的,就這麼簡單,但你現在只是返回了一句話,如果是要返回一個圖片呢?一個檔案呢?這就涉及你自己要負責實現檔案的傳送了,我們學socket傳檔案時,遇到過粘包問題,解決起來挺麻煩的,你現在要自己通過Socket把Http協議裡的各種功能都實現了的話,估計孩子都長大了。與其浪費時間自己寫,不如直接用先人的。
WSGI介紹
WSGI(Web Server Gateway Interface)是一種規範,它定義了使用python編寫的web app(應用程式)與web server(socket服務端)之間介面格式,實現web app與web server間的解耦。
通俗的說:當規範建立後,程式就不再重複編寫web server(socket服務端),而是直接使用現成的實現WSGI的模組(例如:wsgiref、uwsgi、werkzeug),從而讓程式設計師更加專注與業務程式碼
與其重複造輪子,不如直接用現成的。
Python的wsgiref是基於WSGI規範封裝的模組,我們可以在這個模組基礎上開發我們的web server
基於WSGI開發一個WEB伺服器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# -*- coding:utf-8 -*-
# created by Alex Li - 路飛學城
from wsgiref.simple_server import make_server
def run_server(environ, start_response):
"""
當有使用者在瀏覽器上訪問:http://127.0.0.1:8000/, 立即執行該函式並將函式的返回值返回給使用者瀏覽器
:param environ: 請求相關內容,比如瀏覽器型別、版本、來源地址、url等
:param start_response: 響應相關
:return:
"""
start_response( '200 OK' ,[( 'Content-Type' , 'text/html;charset=utf-8' )])
return [bytes( '<h1>我旁邊的這個人長的真醜呀!!' ,encoding = 'utf-8' ),]
if __name__ = = '__main__' :
httpd = make_server( 'localhost' , 8001 ,run_server)
httpd.serve_forever()
|
別人家的網站和我們的網站
你看別人的網站,可以根據URL不同看到不同的內容,比如這個:煎蛋網
但我們剛才自己開發的網站,永遠只能看到同樣的內容。
怎麼辦?我們自己也可以處理url呀
1 # -*- coding:utf-8 -*- 2 # created by Alex Li - 路飛學城 3 4 from wsgiref.simple_server import make_server 5 6 7 def western(): 8 return "歡迎來到歐美專區" 9 10 def japan(): 11 return "歡迎來到日本人專區" 12 13 14 def routers(): 15 """負責把url與對應的方法關聯起來""" 16 urlpatterns = ( 17 ('/western/',western), 18 ('/japan/',japan), 19 ) 20 21 return urlpatterns 22 23 24 def run_server(environ, start_response): 25 """ 26 當有使用者在瀏覽器上訪問:http://127.0.0.1:8000/, 立即執行該函式並將函式的返回值返回給使用者瀏覽器 27 :param environ: 請求相關內容,比如瀏覽器型別、版本、來源地址、url等 28 :param start_response: 響應相關 29 :return: 30 """ 31 start_response('200 OK',[('Content-Type', 'text/html;charset=utf-8')]) 32 url = environ.get("PATH_INFO") 33 urlpatterns = routers() 34 35 func = None 36 37 for item in urlpatterns: 38 if item[0] == url: 39 func = item[1] 40 break 41 if func: 42 return [bytes(func(),encoding="utf-8"),] 43 else: 44 return [bytes('404 not found.',encoding="utf-8"),] 45 46 if __name__ == '__main__': 47 httpd = make_server('localhost',8001,run_server) 48 httpd.serve_forever()
真棒,輕鬆的就可以使你的web server支援多頁面了。但你高興不起來,因為你看到人家別人的網站多姿多彩,各種圖片、各種動效,你的網站只能顯示文字。感覺像是上個世紀的產物,不刺激,哈,那就來點刺激的,讓你的網站也支援一下圖片和樣式。
使自行開發的web server支援圖片
執行一下看看。
真是技術改變生活呀!
能顯示圖片只是冰山一角,我們需要繼續開發一下功能:
- 使用者表單提交,即:使用者向後臺傳送表單資料
- 資料庫操作
- 載入樣式和JS檔案
- 允許使用者下載檔案
雖然自己開發有樂趣,但確實比較麻煩,在專案開發中,追求的更多是效率,而不是樂趣,所以還是儘量不要重複造輪子啦,我們接下來要學的Django框架就是幫我們已經造好的輪子。
Web框架的本質
雖然自己寫Web Server比較麻煩,但是我們從中也瞭解web框架的本質:
- 瀏覽器是socket客戶端,網站是socket服務端
- wsgi,是一個規範,wsgiref實現了這個規範並在其內部實現了socket服務端
- 根據 url 的不同執行不同函式,即:路由系統
- 函式,即:檢視函式
- 圖片、css、js檔案 統一稱為靜態檔案,需要讀取內容直接返回給使用者瀏覽器
Django來了
安裝
1 |
pip3 install django #目前最新版本是2.0
|
* 注意,2.0 跟1.x版本上用法上是有些區別的,本課程我們主講2.x。
安裝成功後,就會出現 django-admin 命令
建立Project
你想做個網站,首先我們要建立一個django project, 以後的程式碼都放在這個專案裡。
1 |
django - admin startproject mysite #專案名是mysite
|
建立好的專案目錄結構
1 2 3 4 5 6 7 8 9 |
mysite
├── manage.py # 管理程式的檔案,啟動和結束等。
└── my site
├── __init__.py
├── settings.py # 程式的配置檔案
├── urls.py # 程式的路由系統,即:url和處理其函式的對應的關係
└── wsgi.py # 指定框架的wsgi
命令幫助我們建立了幾個檔案,通過檔案將功能程式碼歸類。
|
建立APP
一個專案中會包含一個或多個子專案,每個專案實現不同的功能和服務,如微信裡包含基本通訊功能,還有支付、小程式等,每塊業務都可以分為一個子專案。在django中, 我們管這個子專案叫app。下面是一個有多app的專案
為了開發和維護方便,每個子專案(app)都會有一個獨立資料夾來存放各自的業務程式碼。
一般程式簡單情況下,只需要建立一個app即可。
1 |
python manage.py startapp app01 #app01 是app名稱
|
Django的第一次請求
HTTP請求本質
上面的一次django請求都經歷了哪些過程呢?我們來剖析下
瀏覽器訪問網站的本質:socket客戶端、socket服務端之間的收發訊息。
流程:
1. 【服務端】網站啟動,並監聽IP和埠,如:127.0.0.1:80,等待客戶端來連線…
2. 【客戶端】瀏覽器中輸入http://www.oldboyedu.com/index/,瀏覽器先後進行:
- 連線:域名解析得到網站IP,並根據埠進行連線。
- 傳送訊息:將請求資料傳送給服務端,傳送資料本質上是字串,格式如下:
1 2 |
GET / index / http1. 1 \r\nhost:www.luffycity.com…..\r\n\r\n
POST / index / http1. 1 \r\nhost:www.luffycity.com...\r\n\r\nage = 18 &num = 1
3.
|
3. 【服務端】接收使用者請求發來的資料,並根據請求字串解析,並做出響應。
1 |
響應:HTTP / 1.1 200 OK\r\nContent - Type : text / html;...\r\n\r\n<html>...< / html>
|
4. 【客戶端】接收服務端響應的內容,將響應體展示在瀏覽器上,響應頭偷偷儲存到瀏覽器。
5. 【客戶端】【服務端】連線斷開,Http請求終止(體現了Http短連線)。
注意:請求和響應基本包含請求頭和請求體並通過\r\n\r\n進行分割。
用Django 開發使用者登入頁面
使用者登入是個表單啦,但目前我們只會用Django返回字串,表單涉及的html元素比較多,總不能在view.py裡寫好返回吧?這太low了,是的,怎麼可以不low? 是時候表演真正的技術啦。
Django有個叫模板(Template)的東東,可以直接把你的Html程式碼寫在模板裡,返回給瀏覽器。
模板初探
想用模板僅需2步,
- 配置存html檔案的模板目錄
- 在你的views.py的響應函式裡返回對應的html檔案
是時候該講講套路啦
剛才在開發使用者登入頁面時,我們的請求處理流程是這樣的, 請求-> url.py -> views.py -> template -> 瀏覽器, 流程為什麼這樣安排?中間如何要從資料庫裡拿資料,是應該在哪個階段?其實Django或其它web語言的web框架在開發時都符合了某種神祕的套路,這個套路是什麼?即MVC.
MVC 是一種使用 MVC(Model View Controller 模型-檢視-控制器)設計建立 Web 應用程式的模式
不懂對不對?其實說白了,就是把Web開發中一個請求處理流程分成了3部分,每部分專注做自己的事。
- Model(模型)一般對應資料庫操作、紀錄的存取
- View(檢視)決定著如何展示資料
- Controller(控制器)負現處理使用者互動的部分。控制器負責從檢視讀取資料,控制使用者輸入,並向模型傳送資料。
MVC & MTV
Django是一個MTV框架,其架構模板看上去與傳統的MVC架構並沒有太大的區別。Django將MVC中的檢視進一步分解為 Django檢視 和 Django模板兩個部分,分別決定 “展現哪些資料” 和 “如何展現”,使得Django的模板可以根據需要隨時替換,而不僅僅限制於內建的模板。至於MVC控制器部分,由Django框架的URLconf來實現。
再具體點的圖
從下一章開始 ,我們會一點點把model,views,template,url 每個都延伸開來講。