Python高階——mini_web框架(實現web框架介面,資料庫連線)
阿新 • • 發佈:2018-12-09
mini_web框架
http伺服器
import socket
import multiprocessing
import re
import mini_frame
class Http:
def __init__(self):
# 初始化屬性
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True )
self.server_socket.bind(("", 8080))
self.server_socket.listen(128)
def start(self):
# 接收客戶端訊息
while True:
client_socket, ip_port = self.server_socket.accept()
p1 = multiprocessing.Process(target=self.recv_msg, args=(client_socket, ip_port))
p1.start()
client_socket.close()
@staticmethod
def recv_msg(client_socket, ip_port):
print("[客戶端]:", ip_port, "連線")
client_data = client_socket.recv(4096)
# 符合http協議的請求資訊
client_data = client_data.decode()
print(client_data)
if client_data == '':
print("客戶端關閉")
return
# 資料分析 獲取資料路徑
data_list = client_data.split("\r\n")
name = data_list[0]
# get /index.html http/1.1
# 通過正則獲取檔案的名字
result = re.match(r"[^/]+(/[^ ]*)", name)
# 獲取檔名
file_name = result.group(1)
# print(file_name)
# 設定主頁
if file_name == "/":
file_name = "/index.html"
if not file_name.endswith(".py"):
# ./static/index.html
# 獲取路徑資訊
file_path = "./static" + file_name
# 進行檢測看看有沒有這個檔案
try:
f = open(file_path, "rb")
except Exception:
# 沒有這個檔案 傳送應答資訊 not found
response_line = "HTTP/1.1 404 NOT FOUND\r\n"
response_body = "%s 404 not found we will rock you.." % file_name
response_data = response_line + "\r\n" + response_body
client_socket.send(response_data.encode())
else:
# 成功後返回的資訊 找到這個檔案了
file_content = f.read()
# 關閉檔案
f.close()
# 應答資料是檔案讀取出來的 二進位制格式
response_body = file_content
# 4 組織傳送應答資訊
# 應答行
response_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server:python02\r\n"
# response_headers += "Content-Type: text/html; charset=utf-8\r\n"
# 組成應答頭 注意要有空行
response_headr = response_line + response_headers + "\r\n"
# 應答頭是需要編碼
client_socket.send(response_headr.encode())
# 應答體是二進位制的 不需要編碼
client_socket.send(response_body)
finally:
# 為了告訴瀏覽器我的資料傳送完畢了
client_socket.close()
else:
response_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server:python02\r\n"
# 通過介面呼叫動態資源
response_body = mini_frame.application(file_name)
response_data = response_line + response_headers + '\r\n' + response_body
client_socket.send(response_data.encode())
client_socket.close()
if __name__ == '__main__':
http = Http()
http.start()
伺服器框架
from pymysql import *
import re
# 路由列表(一個存放路徑和對應函式的字典)
FUNC_URL_LIST = {}
# 路由裝飾器,新建函式時,將路徑和函式名新增到路由列表中
def route(data):
def func_out(func):
FUNC_URL_LIST[data] = func
def func_in():
func()
return func_in
return func_out
@route("/index.py")
def index():
# 開啟對應資源
with open("./templates/index.html", encoding='utf-8') as f:
content = f.read()
# 建立資料庫連線
conn = connect(host='localhost', port=3306, database='stock_db', user='root', passwd='zsh123', charset='utf8')
# 建立遊標物件
cursor = conn.cursor()
sql = "select * from info;"
# 執行sql語句
cursor.execute(sql)
# 返回sql語句執行結果
stock_data = cursor.fetchall()
# 要替換的html文字
html = ''
# 模板文字
template = """
<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="新增" id="toAdd" name="toAdd" systemidvaule="000007">
</td>
</tr>
"""
# 遍歷sql執行結果中的資料
for i in stock_data:
# 將資料新增到模板中,並新增到html文字中
html += template % (i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7])
# 將響應體原html文本里的{%content%}替換為新html體
content = re.sub(r"{%content%}", html, content)
# 關閉遊標物件和連線
cursor.close()
conn.close()
# 返回響應體
return content
@route("/center.py")
def center():
with open("./templates/center.html", encoding='utf-8') as f:
content = f.read()
conn = connect(host='localhost', port=3306, database='stock_db', user='root', passwd='zsh123', charset='utf8')
cursor = conn.cursor()
sql = "select * from info inner join focus on focus.id=2 order by info.code;"
cursor.execute(sql)
stock_data = cursor.fetchall()
html = ''
template = """
<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>
<a type="button" class="btn btn-default btn-xs" href="/update/000007.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
</td>
<td>
<input type="button" value="刪除" id="toDel" name="toDel" systemidvaule="000007">
</td>
</tr>
"""
for i in stock_data:
html += template % (i[1], i[2], i[3], i[4], i[5], i[6], i[9])
content = re.sub(r"{%content%}", html, content)
cursor.close()
conn.close()
return content
def application(file_name):
try:
# 通過路由列表找到對應的函式,返回執行結果
func = FUNC_URL_LIST[file_name]
return func()
except Exception as e:
# 如果沒有找到或發生異常,丟擲異常
print(e)
return "404 not found!"