第二百五十六節,Web框架

Web框架html

 

Web框架本質python

衆所周知,對於全部的Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。web

舉例:數據庫

#!/usr/bin/env python
#coding:utf-8
import socket #導入單線程通信模塊

def handle_request(client): #發送內容函數
    buf = client.recv(1024)  #設置最大傳輸字節
    client.sendall(bytes("HTTP/1.1 200 OK\r\n\r\n", encoding='utf-8'))  #向客戶端發送內容,以字節形式發送
    client.sendall(bytes("Hello, World歡迎訪問", encoding='utf-8'))         #向客戶端發送內容

def main(): #建立通信函數
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    #建立服務端通信對象
    sock.bind(('localhost',8082))                               #在服務端設置服務端ip和端口
    sock.listen(5)                                              #監聽IP和端口,設置一個參數,表示最多鏈接排隊數量

    while True: #循環
        connection, address = sock.accept() #等待接收客戶端的請求,一旦有客戶端請求鏈接,就會返回兩個值,一個是鏈接對象,一個是客戶端的地址信息,因此須要兩個變量來接收
        handle_request(connection)          #執行handle_request函數,將客戶端請求鏈接傳入handle_request函數
        connection.close()                  #關閉鏈接

if __name__ == '__main__':                  #wds系統下if __name__ == "__main__"才能建立進程,咱們調試不要緊,之後在Linux系統沒這個問題
    main()                                  #執行main函數

上述經過socket來實現了其本質,而對於真實開發中的python web程序來講,通常會分爲兩部分:服務器程序和應用程序。服務器程序負責對socket服務器進行封裝,並在請求到來時,對請求的各類數據進行整理。應用程序則負責具體的邏輯處理。爲了方便應用程序的開發,就出現了衆多的Web框架,例如:Django、Flask、web.py 等。不一樣的框架有不一樣的開發方式,可是不管如何,開發出的應用程序都要和服務器程序配合,才能爲用戶提供服務。這樣,服務器程序就須要爲不一樣的框架提供不一樣的支持。這樣混亂的局面不管對於服務器仍是框架,都是很差的。對服務器來講,須要支持各類不一樣框架,對框架來講,只有支持它的服務器才能被開發出的應用使用。這時候,標準化就變得尤其重要。咱們能夠設立一個標準,只要服務器程序支持這個標準,框架也支持這個標準,那麼他們就能夠配合使用。一旦標準肯定,雙方各自實現。這樣,服務器能夠支持更多支持標準的框架,框架也能夠使用更多支持標準的服務器。瀏覽器

 

因此,對於Web框架來講分爲兩類,一類是即包含了socket服務端,有包含了邏輯處理,一類是隻包含邏輯處理須要另外作socket服務端服務器

 

 

python標準庫提供的獨立WSGI服務器稱爲wsgiref。mvc

WSGI(Web Server Gateway Interface)是一種規範,它定義了使用python編寫的web app與web server之間接口格式,實現web app與web server間的解耦。app

wsgiref模塊,python標準庫提供的獨立WSGI服務器稱爲wsgiref,就是Web框架邏輯處理包含了socket服務端框架

注意:wsgiref模塊在python3以上版本有問題,在2.7上能夠使用,因此下面的列子在2.7上運行的socket

#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server  #引入wsgiref的make_server


def RunServer(environ, start_response):  #建立通信內容函數
    start_response('200 OK', [('Content-Type', 'text/html')]) #HTML方式返回內容
    return '<h1>Hello, web!</h1>' #返回內容


if __name__ == '__main__':
    httpd = make_server('', 8082, RunServer)    #設置訪問端口,和通信內容函數
    httpd.serve_forever()   #執行通信函數

RunServer(environ, start_response)建立通信內容函數,裏面有兩個參數
environ裏面包含用戶的請求信息如ip等
start_response裏面包含返回信息

查看方式:

 

自定義Web框架

1、框架

經過python標準庫提供的wsgiref模塊開發一個本身的Web框架

根據用戶訪問的路徑,給出相應的內容

#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server

def index():            #函數返回字符串index
    return 'index'

def login():            #login
    return 'login'

URLS = {                #設置一個字典,鍵爲路徑名稱,值爲函數名稱
    "/index":index,
    "/login":login,
}

def RunServer(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ['PATH_INFO']  #接收用戶訪問的路徑名稱
    if url in URLS.keys():      #判斷用戶訪問路徑在URLS字典裏是否存在
        furl = URLS[url]        #若是存在經過下標拿到字典裏的函數名稱
        ret = furl()            #執行函數賦值給ret變量,至關於ret等於函數返回字符串
    else:
        ret = "404"             #若是不存在ret變量等於404
    return ret                  #最後將ret變量返回給瀏覽器

if __name__ == '__main__':
    httpd = make_server('', 8082, RunServer)
    httpd.serve_forever()

 

 

2、模板引擎,和MVC

MVC框架,就是歸類後根據文件夾定義的名字

在上一步驟中,對於全部的login、index均返回給用戶瀏覽器一個簡單的字符串,在現實的Web請求中通常會返回一個複雜的符合HTML規則的字符串,因此咱們通常將要返回給用戶的HTML寫在指定文件中,而後再返回。如:

模板引擎歸類,歸類就是爲了之後方便管理

urls.py將映射文件信息寫在這個文件裏,之後要添加映射就在這裏寫

#!/usr/bin/env python
#coding:utf-8
import controller
# 映射文件
URLS = {                #設置一個字典,鍵爲路徑名稱,值爲函數名稱
    "/index":controller.index,
    "/login":controller.login,
}

controller.py邏輯處理文件,根據用戶訪問路徑,給出對應的處理,之後要添加邏輯處理函數就寫在這裏

 

#!/usr/bin/env python
#coding:utf-8
import os                                                 #引入os模塊

# 映射文件對應的函數
def index():                                              #函數返HTML文件內容
    f = open(os.path.join('views','index.html'),'r')      #拼接路徑,打開index.html
    data = f.read()                                       #讀出html文件內容
    f.close()                                             #關閉打開的文件
    return data

def login():
    f = open(os.path.join('views', 'login.html'),'r')
    data = f.read()
    f.close()
    return data

 

start.py模板引擎啓動文件,用於啓動模板引擎,通常不作修改

#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server   #導入wsgiref模塊裏的make_server方法
from urls import  URLS                          #導入映射文件變量

def RunServer(environ, start_response):         #定義RunServer函數,接收請求信息,和發送內容
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ['PATH_INFO']                  #接收用戶訪問的路徑名稱
    if url in URLS.keys():                      #判斷用戶訪問路徑在URLS字典裏是否存在
        furl = URLS[url]                        #若是存在經過下標拿到字典裏的函數名稱
        ret = furl()                            #執行函數賦值給ret變量,至關於ret等於函數返回字符串
    else:
        ret = "404"                             #若是不存在ret變量等於404
    return ret                                  #最後將ret變量返回給瀏覽器

if __name__ == '__main__':
    httpd = make_server('', 8082, RunServer)
    httpd.serve_forever()

views文件夾用於專門存放html文件

models文件夾用於專門存放數據庫處理文件

整理後的結構

Web框架,通常根據存放數據庫處理文件夾的首字母M,存放html文件夾首字母V,邏輯處理文件首字母C,來命名的,這就是mvc框架

Web框架運行圖

 

 

Web框架請求動態內容

對於上述代碼,雖然能夠返回給用戶HTML的內容以現實複雜的頁面,可是仍是存在問題:如何給用戶返回動態內容?

1自定義一套特殊的語法,進行替換

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--{{item}}設置一個表示-->
<h1>{{item}}</h1>
</body>
</html>

 

邏輯處理文件controller.py

#!/usr/bin/env python
#coding:utf-8
import os                                                 #引入os模塊
import time                                               #引入事件模塊
# 映射文件對應的函數
def index():                                              #函數返HTML文件內容
    f = open(os.path.join('views','index.html'),'r')      #拼接路徑,打開index.html
    data = f.read()                                       #讀出html文件內容
    f.close()                                             #關閉打開的文件
    new_data = data.replace("{{item}}",str(time.time()))  #獲取系統時間轉換成字符串,替換html裏的{{item}}
    return new_data def login():
    f = open(os.path.join('views', 'login.html'),'r')
    data = f.read()
    f.close()
    return data

 

 


2使用開源工具jinja2,遵循其指定語法

jinja2模塊Web框架模塊
Template()方法邏輯處理Web框架
render()方法設置html可調用python變量
encode()返回邏輯處理後的網頁字符串給瀏覽器

 

 首先須要安裝jinja2第三方模塊

 邏輯處理文件controller.py

#!/usr/bin/env python
#coding:utf-8
import os                                                 #引入os模塊
from jinja2 import Template                               #引入jinja2模塊
# 映射文件對應的函數
def index():                                              #函數返HTML文件內容
    f = open(os.path.join('views','index.html'),'r')      #拼接路徑,打開index.html
    result = f.read()                                     #讀出html文件內容
    f.close()                                             # 關閉打開的文件
    template = Template(result)                           #將讀出的字符串傳入jinja2模塊的Template方法邏輯處理網頁字符串
    data = template.render(name='John Doe', user_list=['alex', 'eric'])     #render方法向網頁字符串添加python能夠變量
    return data.encode('utf-8')                           #返回邏輯處理後的字符串給瀏覽器

def login():
    f = open(os.path.join('views', 'login.html'),'r')
    data = f.read()
    f.close()
    return data

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{name}}</h1>  <!--{{引用框架邏輯處理設置變量}}-->

    <ul> {% for item in user_list %} <!--{%能夠遠行代碼塊%}-->
        <li>{{item}}</li> {% endfor %} </ul>
</body>
</html>
相關文章
相關標籤/搜索