準備工作
在學習Django
之前,先動手擼一個簡單的WEB
框架來熟悉一下前後端互動的整體流程
本次用到的模組:
1.
wsgiref
,這是一個Python
自帶的模組,用於構建路由與檢視2.
pymysql
,第三方模組,用於資料庫與檢視層進行資料互動3.
jinja2
,第三方模組,用於對前端頁面進行模板渲染
請使用pip install modulename
進行安裝
如果安裝jinja2
失敗,請使用easy_install Jinja2
命令進行安裝
資料互動
其實前面已經有大量的地方討論瀏覽器與後端伺服器如何進行互動,也用socket
進行實現過簡單的互動,但是我們需要在前者基礎上做一個優化,即使用者在位址列輸入什麼路徑,就返回請求的路徑名字。
當這個需求完成後,我們就可以根據不同的請求路徑,返回出不同的HTML
文件資訊,但是使用原生的socket
這個過程會十分的繁瑣,所以用一次就放棄吧。
from socket import *
def run():
server = socket(AF_INET, SOCK_STREAM) # 傳輸層基於TCP協議
server.bind(("127.0.0.1", 8080))
server.listen(5)
while 1:
conn, addr = server.accept()
try: # 防止Windows平臺下Client端異常關閉導致雙向連結崩塌Server端異常的情況發生
data = conn.recv(1024)
if not data: # bug修復:針對類UNIX環境
continue
request_path = data.decode("utf-8").split(" ")[1] # 拿到請求的路徑
conn.sendall(bytes("HTTP/1.1 201 OK \r\n\r\n", "utf8")) # 返回響應頭
conn.sendall(bytes("<h1>{0}</h1>".format(request_path), "utf8")) # 返回響應體
except Exception:
continue
conn.close()
if __name__ == '__main__':
run()
wsgiref
以下是利用wsgiref
實現上面的功能,簡單了許多,並且程式碼變得更加明瞭。
此外新增加了訪問路徑不存在時給出404
錯誤提示。
from wsgiref.simple_server import make_server
def index(request):
return "You visited index"
def login(request):
return "You visited login"
def error(request):
return "404 Resource request error"
urls = [
("/index", index),
("/login", login),
]
def run(request, response):
"""
request:① 請求相關的所有資料
response:② 響應相關的資料
return:③ 返回給瀏覽器的資料
"""
response("200 OK",[]) # 響應首行,響應頭
func = None
request_path = request.get("PATH_INFO") # 拿到路徑
for url in urls:
if request_path == url[0]:
func = url[1]
break # 匹配到後結束for迴圈
if func:
res = func(request)
else:
res = error(request)
return [res.encode("utf-8")]
if __name__ == '__main__':
server = make_server("localhost", 8080, run)
# ③ 實時監聽127.0.0.1:8080地址,只要有連結請求,都交給run函式處理
server.serve_forever() # ④ 開啟服務
程式碼解耦
我們對上述程式碼進行解耦,將不同功能的程式碼放在不同的資料夾下。
-- webproject
-- view # 檢視相關程式碼
-- view.py
-- urls # 路由相關程式碼
-- urls.py
-- run.py # 啟動相關程式碼
# view.py
def index(request):
return "You visited index"
def login(request):
return "You visited login"
def error(request):
return "404 Resource request error"
# urls.py
from view.view import *
urls = [
("/index", index),
("/login", login),
]
# run.py
from wsgiref.simple_server import make_server
from urls.urls import *
def run(request, response):
"""
request:① 請求相關的所有資料
response:② 響應相關的資料
return:③ 返回給瀏覽器的資料
"""
response("200 OK",[]) # 響應首行,響應頭
func = None
request_path = request.get("PATH_INFO") # 拿到路徑
for url in urls:
if request_path == url[0]:
func = url[1]
break # 匹配到後結束for迴圈
if func:
res = func(request)
else:
res = error(request)
return [res.encode("utf-8")]
if __name__ == '__main__':
server = make_server("localhost", 8080, run)
# ③ 實時監聽127.0.0.1:8080地址,只要有連結請求,都交給run函式處理
server.serve_forever() # ④ 開啟服務
返回頁面
繼續上面的流程,已經將程式碼進行解耦了,此時我們新建一個template
資料夾用於專門存放返回的網頁。
並在該資料夾下新建index.html
以及login.html
-- webproject
-- view # 檢視相關程式碼
-- view.py
-- urls # 路由相關程式碼
-- urls.py
-- template # 前端頁面
-- index.html
-- login.html
-- run.py # 啟動相關程式碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css' integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'> <script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js' integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa' crossorigin='anonymous'></script> <title>Document</title> <style> .carousel .item { height: 400px; background-color: #777; } .carousel-inner>.item>img { position: absolute; top: 0; left: 0; min-width: 100%; height: 100%; } </style> </head> <body> <nav class="navbar navbar-inverse"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">INDEX</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="HTTP://127.0.0.1:8080/login">LOGIN</a></li> <li><a href="#">REGISTER</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <div class="container-fluid"> <div class="row"> <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 input-lg-5g bg-primar "> <div class="page-header"> <h1>Example page header <small>Subtext for header</small></h1> </div> </div> <div class="col-xs-3 col-sm-3 col-md-3 col-lg-3"> <div class="list-group"> <a href="#" class="list-group-item active"> Cras justo odio </a> <a href="#" class="list-group-item">Dapibus ac facilisis in</a> <a href="#" class="list-group-item">Morbi leo risus</a> <a href="#" class="list-group-item">Porta ac consectetur ac</a> <a href="#" class="list-group-item">Vestibulum at eros</a> </div> </div> <div class="col-xs-9 col-sm-9 col-md-9 col-lg-9"> <div id="carousel-example-generic" class="carousel slide" data-ride="carousel"> <!-- Indicators --> <ol class="carousel-indicators"> <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li> <li data-target="#carousel-example-generic" data-slide-to="1"></li> </ol> <!-- Wrapper for slides --> <div class="carousel-inner"> <div class="item active"> <img src="https://tse4-mm.cn.bing.net/th/id/OIP._PbxAuEi3ce9S1DtQ3KilwHaEK?w=306&h=180&c=7&o=5&dpr=1.25&pid=1.7" alt="..."> </div> <div class="item"> <img src="https://tse2-mm.cn.bing.net/th/id/OIP.Det5e8us-qsNAGEhnL6u0AHaF7?w=238&h=190&c=7&o=5&dpr=1.25&pid=1.7" alt="..."> </div> </div> <!-- Controls --> <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div> </div> </div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css' integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'> <script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js' integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa' crossorigin='anonymous'></script> <style> body { display: flex; justify-content: center; align-self: center; height: 100vh; background-color: rebeccapurple; } form.form1 { display: flex; flex-flow: column; justify-content: center; align-self: center; border: 1px solid #ddd; padding: 10px; width: 30%; background-color: white; border-radius: 15px; } </style> </head> <body> <form class="form1" action="#"> <div class="form-group"> <label for="exampleInputEmail1">username</label> <input type="email" class="form-control" id="exampleInputEmail1" placeholder="please enter user name"> </div> <div class="form-group"> <label for="exampleInputPassword1">Password</label> <input type="password" class="form-control" id="exampleInputPassword1" placeholder="please enter user password"> </div> <button type="submit" class="btn btn-default" disabled>Submit</button> </form> </body> </html>
除此之外,還要將檢視中index
函式與login
函式的返回結果改一下
# view.py
def index(request):
with open(file="template/index.html",mode="r",encoding="utf-8") as f:
res = f.read()
return res
def login(request):
with open(file="template/login.html",mode="r",encoding="utf-8") as f:
res = f.read()
return res
def error(request):
return "404 Resource request error"
那麼目前,我們的框架已經初具雛形了,能夠根據請求路徑的不同返回不同的HTML
文件。
pymsql
繼續接著做邏輯,點選login
後輸入使用者名稱和密碼提交完應該對資料庫進行驗證,判斷該使用者是否存在。
那麼現在我們就需要用到pymysql
模組了,還是新建一個資料夾叫db
,然後建立db
檔案進行操作。
import pymysql class DbServer(object): def __init__(self): self.conn = pymysql.connect( host="localhost", database="db1", charset="utf8mb4", user="root", cursorclass=pymysql.cursors.DictCursor, # 記錄結果,字典顯示 autocommit=True, # 自動提交 ) self.cursor = self.conn.cursor() def select(self, sql, val=None): res = self.cursor.execute(sql, val) return res, self.cursor.fetchone() # 返回查詢行數,查詢結果 def insert(self, sql, val=None): pass def drop(self, sql, val=None): pass def deletle(self, sql, val=None): pass def __del__(self): # 關閉程式前關閉連結與遊標 self.cursor.close() self.conn.close() if __name__ != '__main__': # 不能當作獨立檔案進行執行 dbserver = DbServer()
記得在資料庫中先插入資料
create table user( id INT PRIMARY KEY AUTO_INCREMENT, name CHAR(12) NOT NULL, password CHAR(12) NOT NULL, INDEX(name) -- 新增索引 ); INSERT INTO user(name,password) VALUES ("Yunya","123456");
別忘了在view.py
中進行匯入,與此同時,還要寫一個驗證功能。
from db.db import dbserver import jinja2 def index(request): with open(file="template/index.html", mode="r", encoding="utf-8") as f: res = f.read() return res def login(request): with open(file="template/login.html", mode="r", encoding="utf-8") as f: res = f.read() return res def login_verif(request): # GET 請求 QUERY_STRING request_msg = request.get("QUERY_STRING", None).split("&") user_dict = {} for msg in request_msg: key, value = msg.split("=") user_dict[key] = value from db.db import dbserver def index(request): with open(file="template/index.html", mode="r", encoding="utf-8") as f: res = f.read() return res def login(request): with open(file="template/login.html", mode="r", encoding="utf-8") as f: res = f.read() return res def login_verif(request): # GET 請求 QUERY_STRING request_msg = request.get("QUERY_STRING", None).split("&") user_dict = {} for msg in request_msg: key, value = msg.split("=") user_dict[key] = value sql = "select * from user where name=%s and password = %s" val = (user_dict.get("username"), user_dict.get("password")) result = dbserver.select(sql, val) if result[0]: return "Welcome" + result[1].get("name") else: return "Login failed, no such user" def error(request): return "404 Resource request error"
還要在urls.py
檔案中增加驗證的路由解析。
from view.view import * urls = [ ("/index", index), ("/login", login), ("/login_verif", login_verif), ]
最後一步修改前端login.html
中的form
提交路徑
<form class="form1" action="http://127.0.0.1:8080/login_verif"> <div class="form-group"> <label for="username">username</label> <input type="text" id="username" name="username" class="form-control" placeholder="please enter user name"> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" id="password" name="password" class="form-control" placeholder="please enter user password"> </div> <button type="submit" class="btn btn-default">Submit</button> </form>
jinja2
在驗證完成後,我們應該根據使用者名稱與密碼是否正確來返回不同的內容。
這個時候可以使用jinja2
的模板語言了。
首先在Template
資料夾下新建一個verification.html
做驗證
然後修改一下view
中的login_verif
程式碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="container"> <div class="row"> <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6 col-xs-offset-3 col-sm-offset-3 col-md-offset-3 col-lg-offset-3 "> <div class="page-header"> {% if login_msg.status %} <h1>歡迎回家{{login_msg.username}}</h1> {% else %} <h1>無此使用者!請檢查使用者名稱或密碼是否輸入正確</h1> {% endif %} </div> </div> </div> </div> </body> </html>
def login_verif(request):
# GET 請求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {}
for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value
sql = "select * from user where name=%s and password = %s"
val = (user_dict.get("username"), user_dict.get("password"))
result = dbserver.select(sql, val)
with open("./template/verification.html","r",encoding="utf-8") as f:
data = f.read()
tmp = jinja2.Template(data) # 做成模板
if result[0]:
msg = {"username":result[1].get("name"),"status":1}
else:
msg = {"username":None,"status":0}
res = tmp.render(login_msg=msg) # 模板中新增變數
return res
成果演示
程式碼總和
db - db.py
import pymysql
class DbServer(object):
def __init__(self):
self.conn = pymysql.connect(
host="localhost",
database="db1",
charset="utf8mb4",
user="root",
cursorclass=pymysql.cursors.DictCursor, # 記錄結果,字典顯示
autocommit=True, # 自動提交
)
self.cursor = self.conn.cursor()
def select(self, sql, val=None):
res = self.cursor.execute(sql, val)
return res, self.cursor.fetchone() # 返回查詢行數,查詢結果
def insert(self, sql, val=None):
pass
def drop(self, sql, val=None):
pass
def deletle(self, sql, val=None):
pass
def __del__(self):
# 關閉程式前關閉連結與遊標
self.cursor.close()
self.conn.close()
if __name__ != '__main__':
dbserver = DbServer()
template - index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css' integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'> <script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js' integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa' crossorigin='anonymous'></script> <title>Document</title> <style> .carousel .item { height: 400px; background-color: #777; } .carousel-inner>.item>img { position: absolute; top: 0; left: 0; min-width: 100%; height: 100%; } </style> </head> <body> <nav class="navbar navbar-inverse"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">INDEX</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="HTTP://127.0.0.1:8080/login">LOGIN</a></li> <li><a href="#">REGISTER</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <div class="container-fluid"> <div class="row"> <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 input-lg-5g bg-primar "> <div class="page-header"> <h1>Example page header <small>Subtext for header</small></h1> </div> </div> <div class="col-xs-3 col-sm-3 col-md-3 col-lg-3"> <div class="list-group"> <a href="#" class="list-group-item active"> Cras justo odio </a> <a href="#" class="list-group-item">Dapibus ac facilisis in</a> <a href="#" class="list-group-item">Morbi leo risus</a> <a href="#" class="list-group-item">Porta ac consectetur ac</a> <a href="#" class="list-group-item">Vestibulum at eros</a> </div> </div> <div class="col-xs-9 col-sm-9 col-md-9 col-lg-9"> <div id="carousel-example-generic" class="carousel slide" data-ride="carousel"> <!-- Indicators --> <ol class="carousel-indicators"> <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li> <li data-target="#carousel-example-generic" data-slide-to="1"></li> </ol> <!-- Wrapper for slides --> <div class="carousel-inner"> <div class="item active"> <img src="https://tse4-mm.cn.bing.net/th/id/OIP._PbxAuEi3ce9S1DtQ3KilwHaEK?w=306&h=180&c=7&o=5&dpr=1.25&pid=1.7" alt="..."> </div> <div class="item"> <img src="https://tse2-mm.cn.bing.net/th/id/OIP.Det5e8us-qsNAGEhnL6u0AHaF7?w=238&h=190&c=7&o=5&dpr=1.25&pid=1.7" alt="..."> </div> </div> <!-- Controls --> <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div> </div> </div> </div> </body> </html>
template - login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script> <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css' integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u' crossorigin='anonymous'> <script src='https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js' integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa' crossorigin='anonymous'></script> <style> body { display: flex; justify-content: center; align-self: center; height: 100vh; background-color: rebeccapurple; } form.form1 { display: flex; flex-flow: column; justify-content: center; align-self: center; border: 1px solid #ddd; padding: 10px; width: 30%; background-color: white; border-radius: 15px; } </style> </head> <body> <form class="form1" action="http://127.0.0.1:8080/login_verif"> <div class="form-group"> <label for="username">username</label> <input type="text" id="username" name="username" class="form-control" placeholder="please enter user name"> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" id="password" name="password" class="form-control" placeholder="please enter user password"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> </body> </html>
template - verifcation.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="container"> <div class="row"> <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6 col-xs-offset-3 col-sm-offset-3 col-md-offset-3 col-lg-offset-3 "> <div class="page-header"> {% if login_msg.status %} <h1>歡迎回家{{login_msg.username}}</h1> {% else %} <h1>無此使用者!請檢查使用者名稱或密碼是否輸入正確</h1> {% endif %} </div> </div> </div> </div> </body> </html>
urls - urls.py
from view.view import *
urls = [
("/index", index),
("/login", login),
("/login_verif", login_verif),
]
view - view.py
from db.db import dbserver
import jinja2
def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res
def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res
def login_verif(request):
# GET 請求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {}
for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value
from db.db import dbserver
def index(request):
with open(file="template/index.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res
def login(request):
with open(file="template/login.html", mode="r", encoding="utf-8") as f:
res = f.read()
return res
def login_verif(request):
# GET 請求 QUERY_STRING
request_msg = request.get("QUERY_STRING", None).split("&")
user_dict = {}
for msg in request_msg:
key, value = msg.split("=")
user_dict[key] = value
sql = "select * from user where name=%s and password = %s"
val = (user_dict.get("username"), user_dict.get("password"))
result = dbserver.select(sql, val)
with open("./template/verification.html","r",encoding="utf-8") as f:
data = f.read()
tmp = jinja2.Template(data)
if result[0]:
msg = {"username":result[1].get("name"),"status":1}
else:
msg = {"username":None,"status":0}
res = tmp.render(login_msg=msg) # 返回登入資訊
return res
def error(request):
return "404 Resource request error"
run.py
from wsgiref.simple_server import make_server
from urls.urls import *
def run(request, response):
"""
request:① 請求相關的所有資料
response:② 響應相關的資料
return:③ 返回給瀏覽器的資料
"""
response("200 OK",[]) # 響應首行,響應頭
func = None
request_path = request.get("PATH_INFO") # 拿到路徑
for url in urls:
if request_path == url[0]:
func = url[1]
break # 匹配到後結束for迴圈
if func:
res = func(request)
else:
res = error(request)
return [res.encode("utf-8")]
if __name__ == '__main__':
server = make_server("localhost", 8080, run)
# ③ 實時監聽127.0.0.1:8080地址,只要有連結請求,都交給run函式處理
server.serve_forever() # ④ 開啟服務
最後結論
其實通過這三個基礎模組,相信你已經瞭解了其基本的流程,但是用這三個模組來做成一個建議的Web
框架還是存在大量的不足。
1.
HTML
檔案程式碼冗餘過度2.提交全部為
GET
方式,這使得密碼等傳輸極度不安全3.原生
SQL
語句操縱資料庫,開發效率偏低4.路由的
URL
解析太過死板,不能靈活解析
這些不足點在Django
框架中都會有非常好的解決方案,因此Django
框架是學習PythonWeb
的首選。
總之前後端互動的大體流程就是這樣,前端給請求路徑,後端根據路徑查詢資料庫中資料並進行處理後返回HTML
文件再由模板語言進行解析(前後端不分離),最終呈現出一個完整的動態頁面。
當然還有很多知識點沒有涉及到,如cookie
,ajax
,許可權管理等等,這些都會在之後慢慢做介紹。