Python開(kāi)發(fā)自定義Web框架的示例詳解
開(kāi)發(fā)自定義Web框架
接收web服務(wù)器的動(dòng)態(tài)資源請(qǐng)求,給web服務(wù)器提供處理動(dòng)態(tài)資源請(qǐng)求的服務(wù)。根據(jù)請(qǐng)求資源路徑的后綴名進(jìn)行判斷:
如果請(qǐng)求資源路徑的后綴名是.html則是動(dòng)態(tài)資源請(qǐng)求, 讓web框架程序進(jìn)行處理。
否則是靜態(tài)資源請(qǐng)求,讓web服務(wù)器程序進(jìn)行處理。
1.開(kāi)發(fā)Web服務(wù)器主體程序
1、接受客戶端HTTP請(qǐng)求(底層是TCP)
# -*- coding: utf-8 -*-
# @File : My_Web_Server.py
# @author: Flyme awei
# @email : 1071505897@qq.com
# @Time : 2022/7/24 21:28
from socket import *
import threading
# 開(kāi)發(fā)自己的Web服務(wù)器主類(lèi)
class MyHttpWebServer(object):
def __init__(self, port):
# 創(chuàng)建 HTTP服務(wù)的 TCP套接字
server_socket = socket(AF_INET, SOCK_STREAM)
# 設(shè)置端口號(hào)互用,程序退出之后不需要等待,直接釋放端口
server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
# 綁定 ip和 port
server_socket.bind(('', port))
# listen使套接字變?yōu)榱吮粍?dòng)連接
server_socket.listen(128)
self.server_socket = server_socket
# 處理請(qǐng)求函數(shù)
@staticmethod # 靜態(tài)方法
def handle_browser_request(new_socket):
# 接受客戶端發(fā)來(lái)的數(shù)據(jù)
recv_data = new_socket.recv(4096)
# 如果沒(méi)有數(shù)據(jù),那么請(qǐng)求無(wú)效,關(guān)閉套接字,直接退出
if len(recv_data) == 0:
new_socket.close()
return
# 啟動(dòng)服務(wù)器,并接受客戶端請(qǐng)求
def start(self):
# 循環(huán)并多線程來(lái)接收客戶端請(qǐng)求
while True:
# accept等待客戶端連接
new_socket, ip_port = self.server_socket.accept()
print("客戶端ip和端口", ip_port)
# 一個(gè)客戶端的請(qǐng)求交給一個(gè)線程來(lái)處理
sub_thread = threading.Thread(target=MyHttpWebServer.handle_browser_request, args=(new_socket, ))
# 設(shè)置當(dāng)前線程為守護(hù)線程
sub_thread.setDaemon(True)
sub_thread.start() # 啟動(dòng)子線程
# Web 服務(wù)器程序的入口
def main():
web_server = MyHttpWebServer(8080)
web_server.start()
if __name__ == '__main__':
main()
2、判斷請(qǐng)求是否是靜態(tài)資源還是動(dòng)態(tài)資源
# 對(duì)接收的字節(jié)數(shù)據(jù)進(jìn)行轉(zhuǎn)換為字符數(shù)據(jù)
request_data = recv_data.decode('utf-8')
print("瀏覽器請(qǐng)求的數(shù)據(jù):", request_data)
request_array = request_data.split(' ', maxsplit=2)
# 得到請(qǐng)求路徑
request_path = request_array[1]
print("請(qǐng)求的路徑是:", request_path)
if request_path == "/":
# 如果請(qǐng)求路徑為根目錄,自動(dòng)設(shè)置為:/index.html
request_path = "/index.html"
# 判斷是否為:.html 結(jié)尾
if request_path.endswith(".html"):
"動(dòng)態(tài)資源請(qǐng)求"
pass
else:
"靜態(tài)資源請(qǐng)求"
pass
3、如果靜態(tài)資源怎么處理?

"靜態(tài)資源請(qǐng)求"
# 根據(jù)請(qǐng)求路徑讀取/static 目錄中的文件數(shù)據(jù),相應(yīng)給客戶端
response_body = None # 響應(yīng)主體
response_header = None # 響應(yīng)頭的第一行
response_first_line = None # 響應(yīng)頭內(nèi)容
response_type = 'test/html' # 默認(rèn)響應(yīng)類(lèi)型
try:
# 讀取 static目錄中相對(duì)應(yīng)的文件數(shù)據(jù),rb模式是一種兼容模式,可以打開(kāi)圖片,也可以打開(kāi)js
with open('static'+request_path, 'rb') as f:
response_body = f.read()
if request_path.endswith('.jpg'):
response_type = 'image/webp'
response_first_line = 'HTTP/1.1 200 OK'
response_header = 'Content-Length:' + str(len(response_body)) + '\r\n' + \
'Content-Type: ' + response_type + '; charset=utf-8\r\n' + \
'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
'Server: Flyme awei Server\r\n'
# 瀏覽器讀取的文件可能不存在
except Exception as e:
with open('static/404.html', 'rb') as f:
response_body = f.read() # 響應(yīng)的主體頁(yè)面內(nèi)容
# 響應(yīng)頭
response_first_line = 'HTTP/1.1 404 Not Found\r\n'
response_header = 'Content-Length:'+str(len(response_body))+'\r\n' + \
'Content-Type: text/html; charset=utf-8\r\n' + \
'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
'Server: Flyme awei Server\r\n'
# 最后都會(huì)執(zhí)行的代碼
finally:
# 組成響應(yīng)數(shù)據(jù)發(fā)送給(客戶端)瀏覽器
response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
new_socket.send(response)
# 關(guān)閉套接字
new_socket.close()

靜態(tài)資源請(qǐng)求驗(yàn)證:

4、如果動(dòng)態(tài)資源又怎么處理
if request_path.endswith(".html"):
"動(dòng)態(tài)資源請(qǐng)求"
# 動(dòng)態(tài)資源的處理交給Web框架來(lái)處理,需要把請(qǐng)求參數(shù)交給Web框架,可能會(huì)有多個(gè)參數(shù),采用字典結(jié)構(gòu)
params = {
'request_path': request_path
}
# Web框架處理動(dòng)態(tài)資源請(qǐng)求后,返回一個(gè)響應(yīng)
response = MyFramework.handle_request(params)
new_socket.send(response)
new_socket.close()
5、關(guān)閉Web服務(wù)器
new_socket.close()
Web服務(wù)器主體框架總代碼展示:
# -*- coding: utf-8 -*-
# @File : My_Web_Server.py
# @author: Flyme awei
# @email : 1071505897@qq.com
# @Time : 2022/7/24 21:28
import sys
import time
from socket import *
import threading
import MyFramework
# 開(kāi)發(fā)自己的Web服務(wù)器主類(lèi)
class MyHttpWebServer(object):
def __init__(self, port):
# 創(chuàng)建 HTTP服務(wù)的 TCP套接字
server_socket = socket(AF_INET, SOCK_STREAM)
# 設(shè)置端口號(hào)互用,程序退出之后不需要等待,直接釋放端口
server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
# 綁定 ip和 port
server_socket.bind(('', port))
# listen使套接字變?yōu)榱吮粍?dòng)連接
server_socket.listen(128)
self.server_socket = server_socket
# 處理請(qǐng)求函數(shù)
@staticmethod # 靜態(tài)方法
def handle_browser_request(new_socket):
# 接受客戶端發(fā)來(lái)的數(shù)據(jù)
recv_data = new_socket.recv(4096)
# 如果沒(méi)有數(shù)據(jù),那么請(qǐng)求無(wú)效,關(guān)閉套接字,直接退出
if len(recv_data) == 0:
new_socket.close()
return
# 對(duì)接收的字節(jié)數(shù)據(jù)進(jìn)行轉(zhuǎn)換為字符數(shù)據(jù)
request_data = recv_data.decode('utf-8')
print("瀏覽器請(qǐng)求的數(shù)據(jù):", request_data)
request_array = request_data.split(' ', maxsplit=2)
# 得到請(qǐng)求路徑
request_path = request_array[1]
print("請(qǐng)求的路徑是:", request_path)
if request_path == "/":
# 如果請(qǐng)求路徑為根目錄,自動(dòng)設(shè)置為:/index.html
request_path = "/index.html"
# 判斷是否為:.html 結(jié)尾
if request_path.endswith(".html"):
"動(dòng)態(tài)資源請(qǐng)求"
# 動(dòng)態(tài)資源的處理交給Web框架來(lái)處理,需要把請(qǐng)求參數(shù)交給Web框架,可能會(huì)有多個(gè)參數(shù),采用字典結(jié)構(gòu)
params = {
'request_path': request_path
}
# Web框架處理動(dòng)態(tài)資源請(qǐng)求后,返回一個(gè)響應(yīng)
response = MyFramework.handle_request(params)
new_socket.send(response)
new_socket.close()
else:
"靜態(tài)資源請(qǐng)求"
# 根據(jù)請(qǐng)求路徑讀取/static 目錄中的文件數(shù)據(jù),相應(yīng)給客戶端
response_body = None # 響應(yīng)主體
response_header = None # 響應(yīng)頭的第一行
response_first_line = None # 響應(yīng)頭內(nèi)容
response_type = 'test/html' # 默認(rèn)響應(yīng)類(lèi)型
try:
# 讀取 static目錄中相對(duì)應(yīng)的文件數(shù)據(jù),rb模式是一種兼容模式,可以打開(kāi)圖片,也可以打開(kāi)js
with open('static'+request_path, 'rb') as f:
response_body = f.read()
if request_path.endswith('.jpg'):
response_type = 'image/webp'
response_first_line = 'HTTP/1.1 200 OK'
response_header = 'Content-Length:' + str(len(response_body)) + '\r\n' + \
'Content-Type: ' + response_type + '; charset=utf-8\r\n' + \
'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
'Server: Flyme awei Server\r\n'
# 瀏覽器讀取的文件可能不存在
except Exception as e:
with open('static/404.html', 'rb') as f:
response_body = f.read() # 響應(yīng)的主體頁(yè)面內(nèi)容
# 響應(yīng)頭
response_first_line = 'HTTP/1.1 404 Not Found\r\n'
response_header = 'Content-Length:'+str(len(response_body))+'\r\n' + \
'Content-Type: text/html; charset=utf-8\r\n' + \
'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
'Server: Flyme awei Server\r\n'
# 最后都會(huì)執(zhí)行的代碼
finally:
# 組成響應(yīng)數(shù)據(jù)發(fā)送給(客戶端)瀏覽器
response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
new_socket.send(response)
# 關(guān)閉套接字
new_socket.close()
# 啟動(dòng)服務(wù)器,并接受客戶端請(qǐng)求
def start(self):
# 循環(huán)并多線程來(lái)接收客戶端請(qǐng)求
while True:
# accept等待客戶端連接
new_socket, ip_port = self.server_socket.accept()
print("客戶端ip和端口", ip_port)
# 一個(gè)客戶端的請(qǐng)求交給一個(gè)線程來(lái)處理
sub_thread = threading.Thread(target=MyHttpWebServer.handle_browser_request, args=(new_socket, ))
# 設(shè)置當(dāng)前線程為守護(hù)線程
sub_thread.setDaemon(True)
sub_thread.start() # 啟動(dòng)子線程
# Web 服務(wù)器程序的入口
def main():
web_server = MyHttpWebServer(8080)
web_server.start()
if __name__ == '__main__':
main()
2.開(kāi)發(fā)Web框架主體程序
1、根據(jù)請(qǐng)求路徑,動(dòng)態(tài)的響應(yīng)對(duì)應(yīng)的數(shù)據(jù)
# -*- coding: utf-8 -*-
# @File : MyFramework.py
# @author: Flyme awei
# @email : 1071505897@qq.com
# @Time : 2022/7/25 14:05
import time
# 自定義Web框架
# 處理動(dòng)態(tài)資源請(qǐng)求的函數(shù)
def handle_request(parm):
request_path = parm['request_path']
if request_path == '/index.html': # 當(dāng)前請(qǐng)求路徑有與之對(duì)應(yīng)的動(dòng)態(tài)響應(yīng),當(dāng)前框架只開(kāi)發(fā)了 index.html的功能
response = index()
return response
else:
# 沒(méi)有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
return page_not_found()
# 當(dāng)前 index函數(shù),專門(mén)處理index.html的請(qǐng)求
def index():
# 需求,在頁(yè)面中動(dòng)態(tài)顯示當(dāng)前系統(tǒng)時(shí)間
data = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
response_body = data
response_first_line = 'HTTP/1.1 200 OK\r\n'
response_header = 'Content-Length:' + str(len(response_body)) + '\r\n' + \
'Content-Type: text/html; charset=utf-8\r\n' + \
'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
'Server: Flyme awei Server\r\n'
response = (response_first_line + response_header + '\r\n' + response_body).encode('utf-8')
return response
def page_not_found():
with open('static/404.html', 'rb') as f:
response_body = f.read() # 響應(yīng)的主體頁(yè)面內(nèi)容
# 響應(yīng)頭
response_first_line = 'HTTP/1.1 404 Not Found\r\n'
response_header = 'Content-Length:' + str(len(response_body)) + '\r\n' + \
'Content-Type: text/html; charset=utf-8\r\n' + \
'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
'Server: Flyme awei Server\r\n'
response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
return response
2、如果請(qǐng)求路徑,沒(méi)有對(duì)應(yīng)的響應(yīng)數(shù)據(jù)也需要返回404頁(yè)面

3.使用模板來(lái)展示響應(yīng)內(nèi)容
1、自己設(shè)計(jì)一個(gè)模板 index.html ,中有一些地方采用動(dòng)態(tài)的數(shù)據(jù)來(lái)替代
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>首頁(yè) - 電影列表</title>
<link href="/css/bootstrap.min.css" rel="stylesheet">
<script src="/js/jquery-1.12.4.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-static-top ">
<div class="container">
<div class="navbar-header">
<button class="navbar-toggle" data-toggle="collapse" data-target="#mymenu">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="#" class="navbar-brand">電影列表</a>
</div>
<div class="collapse navbar-collapse" id="mymenu">
<ul class="nav navbar-nav">
<li class="active"><a href="">電影信息</a></li>
<li><a href="">個(gè)人中心</a></li>
</ul>
</div>
</div>
</div>
<div class="container">
<div class="container-fluid">
<table class="table table-hover">
<tr>
<th>序號(hào)</th>
<th>名稱</th>
<th>導(dǎo)演</th>
<th>上映時(shí)間</th>
<th>票房</th>
<th>電影時(shí)長(zhǎng)</th>
<th>類(lèi)型</th>
<th>備注</th>
<th>刪除電影</th>
</tr>
{%datas%}
</table>
</div>
</div>
</body>
</html>2、怎么替代,替代什么數(shù)據(jù)
response_body = response_body.replace('{%datas%}', data)

4.開(kāi)發(fā)框架的路由列表功能
1、以后開(kāi)發(fā)新的動(dòng)作資源的功能,只需要:
a、增加一個(gè)條件判斷分支
b、增加一個(gè)專門(mén)處理的函數(shù)
2、路由: 就是請(qǐng)求的URL路徑和處理函數(shù)直接的映射。
3、路由表
| 請(qǐng)求路徑 | 處理函數(shù) |
|---|---|
| /index.html | index函數(shù) |
| /user_info.html | user_info函數(shù) |
# 定義路由表
route_list = {
('/index.html', index),
('/user_info.html', user_info)
}
for path, func in route_list:
if request_path == path:
return func()
else:
# 沒(méi)有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
return page_not_found()
注意:用戶的動(dòng)態(tài)資源請(qǐng)求,通過(guò)遍歷路由表找到對(duì)應(yīng)的處理函數(shù)來(lái)完成的。
5.采用裝飾器的方式添加路由
1、采用帶參數(shù)的裝飾器
# -*- coding: utf-8 -*-
# @File : My_Web_Server.py
# @author: Flyme awei
# @email : 1071505897@qq.com
# @Time : 2022/7/24 21:28
# 定義路由表
route_list = []
# route_list = {
# ('/index.html', index),
# ('/user_info.html', user_info)
# }
# 定義一個(gè)帶參數(shù)的裝飾器
def route(request_path): # 參數(shù)就是URL請(qǐng)求
def add_route(func):
# 添加路由表
route_list.append((request_path, func))
@wraps(func)
def invoke(*args, **kwargs):
# 調(diào)用指定的處理函數(shù),并返回結(jié)果
return func()
return invoke
return add_route
# 處理動(dòng)態(tài)資源請(qǐng)求的函數(shù)
def handle_request(parm):
request_path = parm['request_path']
# if request_path == '/index.html': # 當(dāng)前請(qǐng)求路徑有與之對(duì)應(yīng)的動(dòng)態(tài)響應(yīng),當(dāng)前框架只開(kāi)發(fā)了 index.html的功能
# response = index()
# return response
# elif request_path == '/user_info.html': # 個(gè)人中心的功能
# return user_info()
# else:
# # 沒(méi)有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
# return page_not_found()
for path, func in route_list:
if request_path == path:
return func()
else:
# 沒(méi)有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
return page_not_found()
2、在任何一個(gè)處理函數(shù)的基礎(chǔ)上增加一個(gè)添加路由的功能
@route('/user_info.html')
小結(jié):使用帶參數(shù)的裝飾器,可以把我們的路由自動(dòng)的,添加到路由表中。
6.電影列表頁(yè)面的開(kāi)發(fā)案例

1、查詢數(shù)據(jù)
my_web.py
# -*- coding: utf-8 -*-
# @File : My_Web_Server.py
# @author: Flyme awei
# @email : 1071505897@qq.com
# @Time : 2022/7/24 21:28
import socket
import sys
import threading
import time
import MyFramework
# 開(kāi)發(fā)自己的Web服務(wù)器主類(lèi)
class MyHttpWebServer(object):
def __init__(self, port):
# 創(chuàng)建HTTP服務(wù)器的套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 設(shè)置端口號(hào)復(fù)用,程序退出之后不需要等待幾分鐘,直接釋放端口
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
server_socket.bind(('', port))
server_socket.listen(128)
self.server_socket = server_socket
# 處理瀏覽器請(qǐng)求的函數(shù)
@staticmethod
def handle_browser_request(new_socket):
# 接受客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù)
recv_data = new_socket.recv(4096)
# 如果沒(méi)有收到數(shù)據(jù),那么請(qǐng)求無(wú)效,關(guān)閉套接字,直接退出
if len(recv_data) == 0:
new_socket.close()
return
# 對(duì)接受的字節(jié)數(shù)據(jù),轉(zhuǎn)換成字符
request_data = recv_data.decode('utf-8')
print("瀏覽器請(qǐng)求的數(shù)據(jù):", request_data)
request_array = request_data.split(' ', maxsplit=2)
# 得到請(qǐng)求路徑
request_path = request_array[1]
print('請(qǐng)求路徑是:', request_path)
if request_path == '/': # 如果請(qǐng)求路徑為跟目錄,自動(dòng)設(shè)置為/index.html
request_path = '/index.html'
# 根據(jù)請(qǐng)求路徑來(lái)判斷是否是動(dòng)態(tài)資源還是靜態(tài)資源
if request_path.endswith('.html'):
'''動(dòng)態(tài)資源的請(qǐng)求'''
# 動(dòng)態(tài)資源的處理交給Web框架來(lái)處理,需要把請(qǐng)求參數(shù)傳給Web框架,可能會(huì)有多個(gè)參數(shù),所有采用字典機(jī)構(gòu)
params = {
'request_path': request_path,
}
# Web框架處理動(dòng)態(tài)資源請(qǐng)求之后,返回一個(gè)響應(yīng)
response = MyFramework.handle_request(params)
new_socket.send(response)
new_socket.close()
else:
'''靜態(tài)資源的請(qǐng)求'''
response_body = None # 響應(yīng)主體
response_header = None # 響應(yīng)頭
response_first_line = None # 響應(yīng)頭的第一行
# 其實(shí)就是:根據(jù)請(qǐng)求路徑讀取/static目錄中靜態(tài)的文件數(shù)據(jù),響應(yīng)給客戶端
try:
# 讀取static目錄中對(duì)應(yīng)的文件數(shù)據(jù),rb模式:是一種兼容模式,可以打開(kāi)圖片,也可以打開(kāi)js
with open('static' + request_path, 'rb') as f:
response_body = f.read()
if request_path.endswith('.jpg'):
response_type = 'image/webp'
response_first_line = 'HTTP/1.1 200 OK'
response_header = 'Server: Laoxiao_Server\r\n'
except Exception as e: # 瀏覽器想讀取的文件可能不存在
with open('static/404.html', 'rb') as f:
response_body = f.read() # 響應(yīng)的主體頁(yè)面內(nèi)容(字節(jié))
# 響應(yīng)頭 (字符數(shù)據(jù))
response_first_line = 'HTTP/1.1 404 Not Found\r\n'
response_header = 'Server: Laoxiao_Server\r\n'
finally:
# 組成響應(yīng)數(shù)據(jù),發(fā)送給客戶端(瀏覽器)
response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
new_socket.send(response)
new_socket.close() # 關(guān)閉套接字
# 啟動(dòng)服務(wù)器,并且接受客戶端的請(qǐng)求
def start(self):
# 循環(huán)并且多線程來(lái)接受客戶端的請(qǐng)求
while True:
new_socket, ip_port = self.server_socket.accept()
print("客戶端的ip和端口", ip_port)
# 一個(gè)客戶端請(qǐng)求交給一個(gè)線程來(lái)處理
sub_thread = threading.Thread(target=MyHttpWebServer.handle_browser_request, args=(new_socket,))
sub_thread.setDaemon(True) # 設(shè)置當(dāng)前線程為守護(hù)線程
sub_thread.start() # 子線程要啟動(dòng)
# web服務(wù)器程序的入口
def main():
web_server = MyHttpWebServer(8080)
web_server.start()
if __name__ == '__main__':
main()
MyFramework.py
# -*- coding: utf-8 -*-
# @File : My_Web_Server.py
# @author: Flyme awei
# @email : 1071505897@qq.com
# @Time : 2022/7/24 21:28
import time
from functools import wraps
import pymysql
# 定義路由表
route_list = []
# route_list = {
# # ('/index.html',index),
# # ('/userinfo.html',user_info)
# }
# 定義一個(gè)帶參數(shù)裝飾器
def route(request_path): # 參數(shù)就是URL請(qǐng)求
def add_route(func):
# 添加路由到路由表
route_list.append((request_path, func))
@wraps(func)
def invoke(*arg, **kwargs):
# 調(diào)用我們指定的處理函數(shù),并且返回結(jié)果
return func()
return invoke
return add_route
# 處理動(dòng)態(tài)資源請(qǐng)求的函數(shù)
def handle_request(params):
request_path = params['request_path']
for path, func in route_list:
if request_path == path:
return func()
else:
# 沒(méi)有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
return page_not_found()
# if request_path =='/index.html': # 當(dāng)前的請(qǐng)求路徑有與之對(duì)應(yīng)的動(dòng)態(tài)響應(yīng),當(dāng)前框架,我只開(kāi)發(fā)了index.html的功能
# response = index()
# return response
#
# elif request_path =='/userinfo.html': # 個(gè)人中心的功能,user_info.html
# return user_info()
# else:
# # 沒(méi)有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
# return page_not_found()
# 當(dāng)前user_info函數(shù),專門(mén)處理userinfo.html的動(dòng)態(tài)請(qǐng)求
@route('/userinfo.html')
def user_info():
# 需求:在頁(yè)面中動(dòng)態(tài)顯示當(dāng)前系統(tǒng)時(shí)間
date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
# response_body =data
with open('template/user_info.html', 'r', encoding='utf-8') as f:
response_body = f.read()
response_body = response_body.replace('{%datas%}', date)
response_first_line = 'HTTP/1.1 200 OK\r\n'
response_header = 'Server: Laoxiao_Server\r\n'
response = (response_first_line + response_header + '\r\n' + response_body).encode('utf-8')
return response
# 當(dāng)前index函數(shù),專門(mén)處理index.html的請(qǐng)求
@route('/index.html')
def index():
# 需求:從數(shù)據(jù)庫(kù)中取得所有的電影數(shù)據(jù),并且動(dòng)態(tài)展示
# date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
# response_body =data
# 1、從MySQL中查詢數(shù)據(jù)
conn = pymysql.connect(host='localhost', port=3306, user='root', password='******', database='test', charset='utf8')
cursor = conn.cursor()
cursor.execute('select * from t_movies')
result = cursor.fetchall()
# print(result)
datas = ""
for row in result:
datas += '''<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s 億人民幣</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td> <input type='button' value='刪除'/> </td>
</tr>
''' % row
print(datas)
# 把查詢的數(shù)據(jù),轉(zhuǎn)換成動(dòng)態(tài)內(nèi)容
with open('template/index.html', 'r', encoding='utf-8') as f:
response_body = f.read()
response_body = response_body.replace('{%datas%}', datas)
response_first_line = 'HTTP/1.1 200 OK\r\n'
response_header = 'Server: Laoxiao_Server\r\n'
response = (response_first_line + response_header + '\r\n' + response_body).encode('utf-8')
return response
# 處理沒(méi)有找到對(duì)應(yīng)的動(dòng)態(tài)資源
def page_not_found():
with open('static/404.html', 'rb') as f:
response_body = f.read() # 響應(yīng)的主體頁(yè)面內(nèi)容(字節(jié))
# 響應(yīng)頭 (字符數(shù)據(jù))
response_first_line = 'HTTP/1.1 404 Not Found\r\n'
response_header = 'Server: Laoxiao_Server\r\n'
response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
return response2、根據(jù)查詢的數(shù)據(jù)得到動(dòng)態(tài)的內(nèi)容

到此這篇關(guān)于Python開(kāi)發(fā)自定義Web框架的示例詳解的文章就介紹到這了,更多相關(guān)Python Web框架內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
服務(wù)器端jupyter notebook映射到本地瀏覽器的操作
這篇文章主要介紹了服務(wù)器端jupyter notebook映射到本地瀏覽器的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
numpy中np.nditer、flags=[multi_index] 的用法說(shuō)明
這篇文章主要介紹了numpy中np.nditer、flags=['multi_index'] 的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-05-05
Python+matplotlib繪制不同大小和顏色散點(diǎn)圖實(shí)例
這篇文章主要介紹了Python+matplotlib繪制不同大小和顏色散點(diǎn)圖實(shí)例,matplotlib的用法是比較多種多樣的,下面一起看看其中的一個(gè)實(shí)例吧2018-01-01
Python實(shí)現(xiàn)希爾排序算法的原理與用法實(shí)例分析
這篇文章主要介紹了Python實(shí)現(xiàn)希爾排序算法,簡(jiǎn)單講述了希爾排序的原理并結(jié)合具體實(shí)例形式分析了Python希爾排序的具體實(shí)現(xiàn)方法與使用技巧,需要的朋友可以參考下2017-11-11
實(shí)例講解Python中函數(shù)的調(diào)用與定義
這篇文章主要介紹了Python中函數(shù)的調(diào)用與定義,是Python入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-03-03
對(duì)Python中type打開(kāi)文件的方式介紹
下面小編就為大家介紹一下對(duì)Python中type打開(kāi)文件的方式。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
Python?使用?pip?安裝?matplotlib?模塊的方法
matplotlib是python中強(qiáng)大的畫(huà)圖模塊,這篇文章主要介紹了Python?使用?pip?安裝?matplotlib?模塊(秒解版),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02

