一、Web框架
有了wsgi褪储,現(xiàn)在我們只需要專注寫處理函數(shù)相應(yīng)http請求就行。
但是問題又來了慧域,一個網(wǎng)站肯定不止一個url鲤竹,如何處理多個不同的url呢?
而且一個url可以對應(yīng)get和post請求昔榴,當(dāng)然還有其他我們就只考慮這兩個辛藻,一個簡單的想法就是從environ變量取出http請求信息,然后逐個判斷
def application(environ, start_response):
method = environ['REQUEST_METHOD']
path = environ['PATH_INFO']
if method=='GET' and PATH=='/'
return handle_home(environ, start_response)
if method=='POST' and path=='/signin'
return handle_signin(environ, start_response)
如果還有很多url互订,這樣寫下去沒完沒了
解決的手段是一個函數(shù)來處理一個url吱肌,然后怎么知道這個函數(shù)是處理哪個url呢?
這交給web框架來做仰禽。
我們這里用flask
# C:\Users\ljs>pip install flask
然后寫一個app.py,處理3個url氮墨,分別是:
- GET /: 首頁,返回home
- GET /signin: 登錄頁坟瓢,顯示登錄表單
- POST /signin:處理登錄表單勇边,顯示登錄結(jié)果
注意這里同一個url/signin分別有g(shù)et和post兩種請求,映射到兩個處理函數(shù)中
Flask通過Python的裝飾器在內(nèi)部自動地把URL和函數(shù)給關(guān)聯(lián)起來折联,所以粒褒,我們寫出來的代碼就像這樣
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def home():
return '<h1>Home</h1>'
@app.route('/signin', methods=['GET'])
def signin_form():
return '''<form action="/signin" method="post">
<P><input name="username"></P>
<p><input name="password" type="password"></p>
<p><button type="submit">Sign In</button></p>
</form>'''
@app.route('/signin', methods=['post'])
def sigin():
#需要從request對象讀取表單內(nèi)容:
if request.form['username']=='admin' and request.form['password']=='password':
return '<h3>hello, admin!</h3>'
return '<h3>bad username or password.</h3>'
if __name__=='__main__':
app.run()
運(yùn)行app.py,Flask自帶的Server在端口5000上監(jiān)聽
C:\Users\ljs\Desktop>python app.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
打開瀏覽器,輸入首頁地址http://localhost:5000/
再在瀏覽器地址欄輸入http://localhost:5000/signin诚镰,會顯示登錄表單:
輸入用戶名admin和口令password奕坟,登錄成功:
密碼輸錯:
小結(jié)
有了Web框架,我們在編寫Web應(yīng)用時清笨,注意力就從WSGI處理函數(shù)轉(zhuǎn)移到URL+對應(yīng)的處理函數(shù)月杉,這樣,編寫Web App就更加簡單了抠艾。
在編寫URL處理函數(shù)時苛萎,除了配置URL外,從HTTP請求拿到用戶數(shù)據(jù)也是非常重要的。Web框架都提供了自己的API來實現(xiàn)這些功能腌歉。Flask通過request.form['name']來獲取表單的內(nèi)容蛙酪。
二、使用模板
使用了框架后我們發(fā)現(xiàn)問題翘盖,在讓函數(shù)返回html字符串桂塞?如果html代碼很多,還要有css和js馍驯,然后全部寫在函數(shù)里?這也是不現(xiàn)實的阁危。這時候我們就得使用模板了。
1汰瘫、我們要先準(zhǔn)備三個html文檔狂打,這不是一個普通的html文檔,而是嵌入了一些變量和指令吟吝,
home.html
<html>
<head>
<title>Home</title>
</head>
<body>
<h1 style="font-style:italic">Home</h1>
</body>
</html>
form.html
<html>
<head>
<title>Please Sign In</title>
</head>
<body>
{% if message %}
<p style="color:red">{{ message }}</p>
{% endif %}
<form action="/signin" method="post">
<legend>Please sign in:</legend>
<p><input name="username" placeholder="Username" value="{{ username }}"></p>
<p><input name="password" placeholder="Password" type="password"></p>
<p><button type="submit">Sign In</button></p>
</form>
</body>
</html>
signin-ok.html
<html>
<head>
<title>Welcome, {{ username }}</title>
</head>
<body>
<p>Welcome, {{ username }}!</p>
</body>
</html>
登錄失敗的模塊我們在form加點(diǎn)判斷把form重用成失敗的模板就行菱父。
2、然后我們重寫app.py,
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def home():
return render_template('home.html')
@app.route('/signin', methods=['GET'])
def signin_form():
return render_template('form.html')
@app.route('/signin', methods=['POST'])
def signin():
username = request.form['username']
password = request.form['password']
if username=='admin' and password=='password':
return render_template('signin-ok.html', username=username)
return render_template('form.html', message='Bad username or password', username=username)
if __name__ == '__main__':
app.run()
Flask通過render_template()
函數(shù)來實現(xiàn)模板的渲染剑逃。和Web框架類似浙宜,Python的模板也有很多種。Flask默認(rèn)支持的模板是jinja2蛹磺,所以我們先直接安裝jinja2:
C:\Users\ljs\Desktop>pip install jinja2
Requirement already satisfied: jinja2 in c:\programdata\anaconda3\lib\site-packages
Requirement already satisfied: MarkupSafe>=0.23 in c:\programdata\anaconda3\lib\site-packages (from jinja2)
You are using pip version 9.0.1, however version 9.0.2 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
3粟瞬、最后,把模板放到templates文件夾里萤捆,這個文件夾與app.py同目錄裙品,然后啟動app.py,跟前面是一樣的
總結(jié);
上面分離python代碼和html代碼俗或,這個模式叫做mvc模式
Model-View-Controller市怎,中文名“模型-視圖-控制器”。
Python處理URL的函數(shù)就是C:Controller辛慰,Controller負(fù)責(zé)業(yè)務(wù)邏輯区匠,比如檢查用戶名是否存在,取出用戶信息等等帅腌;
包含變量{{ name }}的模板就是V:View驰弄,View負(fù)責(zé)顯示邏輯,通過簡單地替換一些變量速客,View最終輸出的就是用戶看到的HTML戚篙。
MVC中的Model在哪?Model是用來傳給View的溺职,這樣View在替換變量的時候岔擂,就可以從Model中取出相應(yīng)的數(shù)據(jù)位喂。
最后推薦一個送趙雷的畫。