<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] >[success] # 嘗試搭建框架 ~~~ 我們所要做的工程目錄劃分 1.一個db 文件夾用來存儲數據 2.一個models 文件夾用來操作數據 3.一個static文件夾用來保存靜態文件 4.一個templates 用來保存html 5.一個routes.py 用來做路由映射 6.一個server.py 用來做啟動文件 7.一個utils.py 用來配置log ~~~ >[info] ## 編寫記錄log -- utils.py ~~~ import time def log(*args, **kwargs): # time.time() 返回 unix time format = '%Y/%m/%d %H:%M:%S' value = time.localtime(int(time.time())) dt = time.strftime(format, value) print(dt, *args, **kwargs) ~~~ >[info] ## 編寫服務器入口文件--server.py ~~~ 1.Request 類進行,保存不同路由映射函數信息 2.response_for_path 處理run中獲取的地址進行路由映射 3.run 方法用來啟動server服務器 ~~~ >[danger] ##### Request 保存路由映射對應請求信息類 ~~~ 1.初始化參數 method 記錄每一個映射路由的請求 2.path 記錄每一個路由的地址路徑 3.body 保存每一個路由的body 內容主要針對post 4.query 記錄每一個get請求鏈接上的參數 配合parsed_path 函數 5.form 用來處理post 請求參數urllib.parse .unquote(v) 處理v 是因為post 的時候空格是+ ~~~ ~~~ class Request: def __init__(self): self.method = "GET" self.path = "" self.body = "" self.query = {} def form(self): args = self.body.split("&") f = {} for arg in args: k, v = arg.split("=") f[k] = urllib.parse .unquote(v) return f # 實例化對象 request = Reuqest() ~~~ >[danger] ##### parsed_path 處理get 請求 ~~~ def parsed_path(path): index = path.find("?") if index == -1: return path, {} else: path, query_string = path.split("?", 1) args = query_string.split("&") query = {} for arg in args: k, v = arg.split('=') query[k] = v return path, query ~~~ >[danger] ##### 編寫一個異常處理的erro文件返回404 ~~~ def error(request, code=404): e = { 404: b'HTTP/1.1 404 NOT FOUND\r\n\r\n<h1>NOT FOUND</h1>', } return e.get(code, b'') ~~~ >[danger] ##### response_for_path 處理路由映射關系 ~~~ 1.parsed_path用來處理 get 請求方法,將get 請求方法清洗,返回地址和請求參數 2.return 返回的是將路由映射保存的request 對象傳入到對應的映射方法 ~~~ ~~~ def response_for_path(path): # 如果你是get path, query = parsed_path(path) request.path = path request.query = query r = { "/static":route_static, } r.update(urls) response = r.get(path, error) return response(request) ~~~ >[danger] ##### run 啟動服務器文件 ~~~ def run(host='', port=3000): # 在控制臺打印端口,和服務器啟動時間 log('start at', '{}:{}'.format(host, port)) # 使用 with 可以保證程序中斷的時候正確關閉 socket 釋放占用的端口 with socket.socket() as s: s.bind((host, port)) while True: s.listen(5) connection, address = s.accept() r = b"" buffer_size = 1024 while True: r_connection = connection.recv(buffer_size) r += r_connection if len(r_connection) <= 1024: break r = r.decode('utf-8') if len(r.split())<2: continue # 拆分原始數據 獲取 請求方法和路徑 GET / HTTP/1.1 path = r.split()[1] request.method = r.split()[0] # 利用"\r\n\r\n" 是將請求體分割格式,獲取請求體 request.body = r.split("\r\n\r\n", 1)[1] # 路由映射 response = response_for_path(path) connection.sendall(response) # 處理完請求, 關閉連接 connection.close() ~~~ >[info] ## 路由映射文件 -- routes.py ~~~ 1.這個文件主要處理每一個,映射函數的請求 2.核對templates 文件的搭配 3.以及處理一些簡單的模板 ~~~ >[danger] ##### 處理讀取HTML函數的 -- template ~~~ 1.注意一定要對open 中的encoding 進行編碼,win默認是gbk模式 ~~~ ~~~ def template(name): path = "template/" + name with open(path, "r",encoding='utf-8') as f: return f.read() ~~~ >[danger] ##### 配置url 參數映射字典 ~~~ urls = { '/': route_index, '/login': route_login, '/register': route_register, '/messages': route_message, } ~~~ >[danger] ##### 編寫靜態文件的映射函數 -- route_static ~~~ def route_static(request): """ 兩種情況的處理 path, query = response_for_path('/static?file=doge.gif') path '/static' """ filename = request.query.get('file', 'doge.gif') path = 'static/' + filename with open(path, 'rb') as f: header = b'HTTP/1.1 200 OK\r\nContent-Type: image/gif\r\n' img = header + b'\r\n'+ f.read() return img ~~~ >[danger] ##### 編寫第一個主頁映射函數 -- route_index ~~~ def route_index(request): """ 主頁的處理函數, 返回主頁的響應 """ header = 'HTTP/1.1 210 VERY OK\r\nContent-Type: text/html\r\n' body = template('index.html') r = header + '\r\n' + body return r.encode(encoding='utf-8') ~~~ >[danger] ##### 編寫登錄邏輯處理的---route_login ~~~ 1.傳的參數中的request 保存的是每一個函數的,請求時候的處理信息 2.如果是post 請求處理創建的Request 類中form 方法保存的body中的內容 3.利用replace 替代我們在html 中特殊格式化的數據,這個頁面最后渲染不應該屬于任何請求,而是所有請求處理的展示內 容改變 ~~~ ~~~ def route_login(request): header = 'HTTP/1.1 210 VERY OK\r\nContent-Type: text/html\r\n' if request.method == 'POST': form = request.form() u = User.new(form) if u.validate_login(): result = '登錄成功' else: result = '用戶名或者密碼錯誤' else: result = '' body = template('login.html') body = body.replace('{{result}}', result) r = header + '\r\n' + body return r.encode(encoding='utf-8') ~~~ >[danger] ##### 編寫注冊處理函數 --- route_register ~~~ def route_register(request): header = 'HTTP/1.1 210 VERY OK\r\nContent-Type: text/html\r\n' if request.method == 'POST': # HTTP BODY 如下 # username=gw123&password=123 # 經過 request.form() 函數之后會變成一個字典 form = request.form() u = User.new(form) if u.validate_register(): u.save() result = '注冊成功<br> <pre>{}</pre>'.format(User.all()) else: result = '用戶名或者密碼長度必須大于2' else: result = '' body = template('register.html') body = body.replace('{{result}}', result) r = header + '\r\n' + body return r.encode(encoding='utf-8') ~~~ >[danger] ##### 模擬簡單的psot get請求 ---route_message ~~~ # message_list 存儲了所有的 message message_list = [] def route_message(request): log('本次請求的 method', request.method) if request.method == 'POST': form = request.form() msg = Message.new(form) log('post', form) message_list.append(msg) # 應該在這里保存 message_list header = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n' body = template('html_basic.html') # '#'.join(['a', 'b', 'c']) 的結果是 'a#b#c' msgs = '<br>'.join([str(m) for m in message_list]) body = body.replace('{{messages}}', msgs) r = header + '\r\n' + body return r.encode(encoding='utf-8') ~~~ >[info] ## 編寫數據處理文件夾 model ~~~ 1.我們處理數據庫的連接模塊進行拆分,成三個小py文件 2.__init__.py用來編寫model 的父類和數據存放方法 3.user.py 用來處理用戶信息判斷驗證 4.message.py 用來處理信息驗證 ~~~ >[danger] # 編寫__init__文件 ~~~ 1.class Model 類用來處理文件的保存和讀取 --- 注意這個類幾點說明 --- db_path 中使用了cls.__name__ 的方法,可以獲取使用類的類名,因為類名和對象不同點在于,類名是唯一的,做成 父類后所有子類就變成唯一的 --- new 相當于創建了對應的類 --- all 是獲取了所有儲存文件的內容 --- save 將所有內容保存到文件目錄中 2.save 方法用來保存文件信息 3.load 用來加載文件信息 ~~~ ~~~ def save(data, path): """ 本函數把一個 dict 或者 list 寫入文件 data 是 dict 或者 list path 是保存文件的路徑 indent 是縮進 ensure_ascii=False 用于保存中文 """ s = json.dumps(data, indent=2, ensure_ascii=False) with open(path, 'w+', encoding='utf-8') as f: log('save', path, s, data) f.write(s) def load(path): """ 本函數從一個文件中載入數據并轉化為 dict 或者 list path 是保存文件的路徑 """ with open(path, 'r', encoding='utf-8') as f: s = f.read() log('load', s) return json.loads(s) # Model 是用于存儲數據的基類 class Model(object): @classmethod def db_path(cls): classname = cls.__name__ path = 'db/{}.txt'.format(classname) return path @classmethod def new(cls, form): # 下面一句相當于 User(form) 或者 Msg(form) m = cls(form) return m @classmethod def all(cls): """ 得到一個類的所有存儲的實例 """ path = cls.db_path() models = load(path) log('log', models) ms = [cls.new(m) for m in models] return ms def save(self): """ save 函數用于把一個 Model 的實例保存到文件中 """ models = self.all() log('models', models) models.append(self) # __dict__ 是包含了對象所有屬性和值的字典 l = [m.__dict__ for m in models] log("lmodel", l) path = self.db_path() save(l, path) def __repr__(self): """ 對象的顯示形式,__dict__ 返回的是初始化 參數 """ classname = self.__class__.__name__ properties = ['{}: ({})'.format(k, v) for k, v in self.__dict__.items()] s = '\n'.join(properties) return '< {}\n{} >\n'.format(classname, s) ~~~ >[danger] 用來進行用戶注冊登錄判斷的 user.py ~~~ from models import Model class User(Model): def __init__(self, form): self.username = form.get('username', '') self.password = form.get('password', '') def validate_login(self): return self.username == 'gua' and self.password == '123' def validate_register(self): return len(self.username) > 2 and len(self.password) > 2 ~~~ >[danger] 用來進行簡單的post,get message.py ~~~ from models import Model # 定義一個 class 用于保存 message class Message(Model): def __init__(self, form): self.author = form.get('author', '') self.message = form.get('message', '') ~~~ >[info] ## html 文件 >[danger] ##### login.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注冊登錄頁面</title> </head> <body> <h1>登錄</h1> <form action="/login" method="post"> <input type="text" name="username" placeholder="請輸入用戶名"> <br> <input type="text" name="password" placeholder="請輸入密碼"> <br> <button type="submit">登錄</button> </form> <h3>{{result}}</h3> </body> </html> ~~~ >[danger] ##### register.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注冊頁面</title> </head> <body> <h1>注冊</h1> <form action="/register" method="post"> <input type="text" name="username" placeholder="請輸入用戶名"> <br> <input type="text" name="password" placeholder="請輸入密碼"> <br> <button type="submit">注冊</button> </form> <h3>{{result}}</h3> </body> </html> ~~~ >[danger] ##### index.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>吃瓜主頁</title> </head> <body> <h1>吃瓜</h1> <a href="/login">Login</a> <img src="/static?file=doge.gif"/> <img src="/static?file=doge1.jpg"/> <img src="/static?file=doge2.gif"/> </body> </html> ~~~ >[danger] ##### html_basic.html ~~~ <!DOCTYPE html> <!-- 注釋是這樣的, 不會被顯示出來 --> <!-- html 格式是瀏覽器使用的標準網頁格式 簡而言之就是 標簽套標簽 --> <!-- html 中是所有的內容 --> <html> <!-- head 中是放一些控制信息, 不會被顯示 --> <head> <!-- meta charset 指定了頁面編碼, 否則中文會亂碼 --> <meta charset="utf-8"> <!-- title 是瀏覽器顯示的頁面標題 --> <title>例子 1</title> </head> <!-- body 中是瀏覽器要顯示的內容 --> <body> <!-- html 中的空格是會被轉義的, 所以顯示的和寫的是不一樣的 --> <!-- 代碼寫了很多空格, 顯示的時候就只有一個 --> 很 好普通版 <h1>很好 h1 版</h1> <h2>很好 h2 版</h2> <h3>很好 h3 版</h3> <!-- form 是用來給服務器傳遞數據的 tag --> <!-- action 屬性是 path --> <!-- method 屬性是 HTTP方法 一般是 get 或者 post --> <!-- get post 的區別上課會講 --> <form action="/messages" method="post"> <!-- textarea 是一個文本域 --> <!-- name 屬性, 用處上課講 --> <textarea name="message"></textarea> <textarea name="author"></textarea> <!-- button type=submit 才可以提交表單 --> <button type="submit">POST 提交</button> </form> <form action="/messages" method="get"> <textarea name="message"></textarea> <button type="submit">GET 提交</button> </form> {{messages}} </body> </html> ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看