1. 程式人生 > >Django入門系列之(Web框架)

Django入門系列之(Web框架)

一 web框架

Web框架(Web framework)是一種開發框架,用來支援動態網站、網路應用和網路服務的開發。這大多數的web框架提供了一套開發和部署網站的方式,也為web行為提供了一套通用的方法。web框架已經實現了很多功能,開發人員使用框架提供的方法並且完成自己的業務邏輯,就能快速開發web應用了。瀏覽器和伺服器的是基於HTTP協議進行通訊的。也可以說web框架就是在以上十幾行程式碼基礎張擴展出來的,有很多簡單方便使用的方法,大大提高了開發的效率。

wsgiref模組

最簡單的Web應用就是先把HTML用檔案儲存好,用一個現成的HTTP伺服器軟體,接收使用者請求,從檔案中讀取HTML,返回。

如果要動態生成HTML,就需要把上述步驟自己來實現。不過,接受HTTP請求、解析HTTP請求、傳送HTTP響應都是苦力活,如果我們自己來寫這些底層程式碼,還沒開始寫動態HTML呢,就得花個把月去讀HTTP規範。

正確的做法是底層程式碼由專門的伺服器軟體實現,我們用Python專注於生成HTML文件。因為我們不希望接觸到TCP連線、HTTP原始請求和響應格式,所以,需要一個統一的介面協議來實現這樣的伺服器軟體,讓我們專心用Python編寫Web業務。這個介面就是WSGI:Web Server Gateway Interface。而wsgiref模組就是python基於wsgi協議開發的服務模組。

  wsgiref簡單應用

二 手擼自己的Web框架

models.py

連結資料庫返回字典格式:
cursor=pymysql.cursors.DictCursor

  建立資料表
import pymysql
#連線資料庫
conn = pymysql.connect(host='127.0.0.1',port= 3306,user = 'root',passwd='123456',db='web') #db:庫名
#建立遊標
cur = conn.cursor()

sql='''
create table userinfo(
        id INT PRIMARY KEY ,
        name VARCHAR(32) ,
        password VARCHAR(32)
)

''' cur.execute(sql) #提交 conn.commit() #關閉指標物件 cur.close() #關閉連線物件 conn.close()
複製程式碼

myserver.py

  啟動檔案
from wsgiref.simple_server import make_server

from urls import url_patters

def mya(environ, start_response):
    # print(environ)
    start_response('200 OK', [('Content-Type', 'text/html')])
    func = None
    for item in url_patters:
        if item[0] == environ.get('PATH_INFO'):
            func = item[1]
            break
    if func:
        data = func(environ)
        return [data]
    else:
        return [b'404']


if __name__ == '__main__':
    myserver = make_server('', 8011, mya)
    print('監聽8010')
    myserver.serve_forever()

urls.py

  路由配置
from views import *
url_patters = [
    ('/login', login),
    ('/index', index),
    ('/time', time),
]

views.py

  檢視函式
def index(environ):
    with open('templates/index.html', 'rb') as f:
        data = f.read()
    return data
def time(environ):
    import datetime
    now=datetime.datetime.now().strftime('%y-%m-%d %X')
    print(now)
    return now.encode('utf-8')
from urllib.parse import parse_qs
import pymysql
def login(request):
    if request.get("REQUEST_METHOD") == "POST":
        try:
            request_body_size = int(request.get('CONTENT_LENGTH', 0))
        except (ValueError):
            request_body_size = 0

        request_body = request['wsgi.input'].read(request_body_size)
        data = parse_qs(request_body)

        user = data.get(b"user")[0].decode("utf8")
        pwd = data.get(b"pwd")[0].decode("utf8")

        # 連線資料庫
        conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='web')  # db:庫名
        # 建立遊標
        cur = conn.cursor()
        SQL = "select * from userinfo WHERE NAME ='%s' AND PASSWORD ='%s'" % (user, pwd)
        cur.execute(SQL)

        if cur.fetchone():

            f = open("templates/backend.html", "rb")
            data = f.read()
            data = data.decode("utf8")
            return data.encode("utf8")

        else:
            print("OK456")
            return b"user or pwd is wrong"

    else:
        f = open("templates/login.html", "rb")
        data = f.read()
        f.close()
        return data

tempaltes下

  backend.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
登入成功
</body>
</html>
  index <! DOCTYPE html >
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
index
</body>
</html>
    login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h4>登入頁面</h4>
<form action="http://127.0.0.1:8011/login" method="post">
     使用者名稱 <input type="text" name="user">
     密碼 <input type="text" name="pwd">
    <input type="submit">
</form>
</body>
</html>

 三 其它socket服務端

    'cgi': CGIServer,
    'flup': FlupFCGIServer,
    'wsgiref': WSGIRefServer,
    'waitress': WaitressServer,
    'cherrypy': CherryPyServer,
    'paste': PasteServer,
    'fapws3': FapwsServer,
    'tornado': TornadoServer,
    'gae': AppEngineServer,
    'twisted': TwistedServer,
    'diesel': DieselServer,
    'meinheld': MeinheldServer,
    'gunicorn': GunicornServer,
    'eventlet': EventletServer,
    'gevent': GeventServer,
    'geventSocketIO':GeventSocketIOServer,
    'rocket': RocketServer,
    'bjoern' : BjoernServer,
    'auto': AutoServer,

一 web框架

Web框架(Web framework)是一種開發框架,用來支援動態網站、網路應用和網路服務的開發。這大多數的web框架提供了一套開發和部署網站的方式,也為web行為提供了一套通用的方法。web框架已經實現了很多功能,開發人員使用框架提供的方法並且完成自己的業務邏輯,就能快速開發web應用了。瀏覽器和伺服器的是基於HTTP協議進行通訊的。也可以說web框架就是在以上十幾行程式碼基礎張擴展出來的,有很多簡單方便使用的方法,大大提高了開發的效率。

wsgiref模組

最簡單的Web應用就是先把HTML用檔案儲存好,用一個現成的HTTP伺服器軟體,接收使用者請求,從檔案中讀取HTML,返回。

如果要動態生成HTML,就需要把上述步驟自己來實現。不過,接受HTTP請求、解析HTTP請求、傳送HTTP響應都是苦力活,如果我們自己來寫這些底層程式碼,還沒開始寫動態HTML呢,就得花個把月去讀HTTP規範。

正確的做法是底層程式碼由專門的伺服器軟體實現,我們用Python專注於生成HTML文件。因為我們不希望接觸到TCP連線、HTTP原始請求和響應格式,所以,需要一個統一的介面協議來實現這樣的伺服器軟體,讓我們專心用Python編寫Web業務。這個介面就是WSGI:Web Server Gateway Interface。而wsgiref模組就是python基於wsgi協議開發的服務模組。

複製程式碼
from wsgiref.simple_server import make_server

def mya(environ, start_response):
    print(environ)
    start_response('200 OK', [('Content-Type', 'text/html')])
    if environ.get('PATH_INFO') == '/index':
        with open('index.html','rb') as f:
            data=f.read()

    elif environ.get('PATH_INFO') == '/login':
        with open('login.html', 'rb') as f:
            data = f.read()
    else:
        data=b'<h1>Hello, web!</h1>'
    return [data]

if __name__ == '__main__':
    myserver = make_server('', 8011, mya)
    print('監聽8010')
    myserver.serve_forever()
複製程式碼

二 手擼自己的Web框架

models.py

連結資料庫返回字典格式:
cursor=pymysql.cursors.DictCursor

複製程式碼
import pymysql
#連線資料庫
conn = pymysql.connect(host='127.0.0.1',port= 3306,user = 'root',passwd='123456',db='web') #db:庫名
#建立遊標
cur = conn.cursor()

sql='''
create table userinfo(
        id INT PRIMARY KEY ,
        name VARCHAR(32) ,
        password VARCHAR(32)
)

'''

cur.execute(sql)

#提交
conn.commit()
#關閉指標物件
cur.close()
#關閉連線物件
conn.close()
複製程式碼

myserver.py

複製程式碼
from wsgiref.simple_server import make_server

from urls import url_patters

def mya(environ, start_response):
    # print(environ)
    start_response('200 OK', [('Content-Type', 'text/html')])
    func = None
    for item in url_patters:
        if item[0] == environ.get('PATH_INFO'):
            func = item[1]
            break
    if func:
        data = func(environ)
        return [data]
    else:
        return [b'404']


if __name__ == '__main__':
    myserver = make_server('', 8011, mya)
    print('監聽8010')
    myserver.serve_forever()
複製程式碼

urls.py

from views import *
url_patters = [
    ('/login', login),
    ('/index', index),
    ('/time', time),
]

views.py

複製程式碼
def index(environ):
    with open('templates/index.html', 'rb') as f:
        data = f.read()
    return data
def time(environ):
    import datetime
    now=datetime.datetime.now().strftime('%y-%m-%d %X')
    print(now)
    return now.encode('utf-8')
from urllib.parse import parse_qs
import pymysql
def login(request):
    if request.get("REQUEST_METHOD") == "POST":
        try:
            request_body_size = int(request.get('CONTENT_LENGTH', 0))
        except (ValueError):
            request_body_size = 0

        request_body = request['wsgi.input'].read(request_body_size)
        data = parse_qs(request_body)

        user = data.get(b"user")[0].decode("utf8")
        pwd = data.get(b"pwd")[0].decode("utf8")

        # 連線資料庫
        conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='web')  # db:庫名
        # 建立遊標
        cur = conn.cursor()
        SQL = "select * from userinfo WHERE NAME ='%s' AND PASSWORD ='%s'" % (user, pwd)
        cur.execute(SQL)

        if cur.fetchone():

            f = open("templates/backend.html", "rb")
            data = f.read()
            data = data.decode("utf8")
            return data.encode("utf8")

        else:
            print("OK456")
            return b"user or pwd is wrong"

    else:
        f = open("templates/login.html", "rb")
        data = f.read()
        f.close()
        return data
複製程式碼

tempaltes下

複製程式碼
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
登入成功
</body>
</html>
複製程式碼 複製程式碼
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
index
</body>
</html>
複製程式碼 複製程式碼
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h4>登入頁面</h4>
<form action="http://127.0.0.1:8011/login" method="post">
     使用者名稱 <input type="text" name="user">
     密碼 <input type="text" name="pwd">
    <input type="submit">
</form>
</body>
</html>
複製程式碼

 三 其它socket服務端

    'cgi': CGIServer,
    'flup': FlupFCGIServer,
    'wsgiref': WSGIRefServer,
    'waitress': WaitressServer,
    'cherrypy': CherryPyServer,
    'paste': PasteServer,
    'fapws3': FapwsServer,
    'tornado': TornadoServer,
    'gae': AppEngineServer,
    'twisted': TwistedServer,
    'diesel': DieselServer,
    'meinheld': MeinheldServer,
    'gunicorn': GunicornServer,
    'eventlet': EventletServer,
    'gevent': GeventServer,
    'geventSocketIO':GeventSocketIOServer,
    'rocket': RocketServer,
    'bjoern' : BjoernServer,
    'auto': AutoServer,