當前位置:首頁 » 編程語言 » pythonweb模板

pythonweb模板

發布時間: 2023-08-03 16:29:07

⑴ 純 python 寫一個 Web 框架,就是這么簡單

造輪子是最好的一種學習方式,本文嘗試從0開始造個Python Web框架的輪子,我稱它為 ToyWebF 。

本文操作環境為:MacOS,文中涉及的命令,請根據自己的系統進行替換。

ToyWebF的簡單特性:

下面我們來實現這些特性。

首先,我們需要安裝gunicorn,回憶一下Flask框架,該框架有內置的Web伺服器,但不穩定,所以上線時通常會替換成uWSGI或gunicorn,這里不搞這個內置Web服務,直接使用gunicorn。

我們創建新的目錄與Python虛擬環境,在該虛擬環境中安裝gunicorn

在啥都沒有的情況下,構建最簡單的Web服務,在ToyWebF目錄下,創建app.py與api.py文件,寫入下面代碼。

運行 gunicorn app:app 訪問 http://127.0.0.1:8000 ,可以看見 Hello, World! ,但現在請求體中的參數在environ變數中,難以解析,我們返回的response也是bytes形式。

我們可以使用webob庫,將environ中的數據轉為Request對象,將需要返回的數據轉為Response對象,處理起來更加直觀方便,直接通過pip安裝一下。

然後修改一下API類的 __call__方法 ,代碼如下。

上述代碼中,通過webob庫的Request類將environ對象(請求的環境信息)轉為容易處理的request,隨後調用handle_request方法對request進行處理,處理的結果,通過response對象返回。

handle_request方法在ToyWebF中非常重要,它會匹配出某個路由對應的處理方法,然後調用該方法處理請求並將處理的結果返回,在解析handle_request前,需要先討論路由注冊實現,代碼如下。

其實就是將路由和方法存到self.routes字典中,可以通過route裝飾器的形式將路由和方法關聯,也可以通過add_route方法關聯,在app.py中使用一下。

因為url中可以存在變數,如 @app.route("/hello/{name}") ,所以在匹配時,需要進行解析,可以使用正則匹配的方式進行匹配,parse這個第三方庫已經幫我們實現了相應的正則匹配邏輯,pip安裝使用一下則可。

這里定義find_handler方法來實現對self.routes的遍歷。

了解了路由與方法關聯的原理後,就可以實現handle_request方法,該方法主要的路徑就是根據路由調度對應的方法,代碼如下。

在該方法中,首先實例化webob庫的Response對象,然後通過self.find_handler方法獲取此次請求路由對應的方法和對應的參數,比如。

它將返回hello方法對象和name參數,如果是 /hello/二兩 ,那麼name就是二兩。

因為route裝飾器可能裝飾器的類對象,比如。

此時self.find_handler方法返回的hanler就是個類,但我們希望調用的是類中的get、post、delete等方法,所以需要一個簡單的判斷邏輯,通過inspect.isclass方法判斷handler如果是類對象,那麼就通過getattr方法獲取類對象實例的中對應的請求方法。

如果類對象中沒有該方法屬性,則拋出該請求類型不被允許的錯誤,如果不是類對象或類對象中存在該方法屬性,則直接調用則可。

此外,如果方法的路由並沒有注冊到self.routes中,即404的情況,定義了defalut_response方法返回其中內容,代碼如下。

如果handle_request方法中調度的過程出現問題,則直接raise將錯誤拋出。

至此,一個最簡單的web服務就編寫完成了。

回顧Flask,Flask可以支持HTML、CSS、javaScript等靜態文件,利用模板語言,可以構建出簡單但美觀的Web應用,我們讓TopWebF也支持這一功能,最終實現圖中的網站,完美兼容靜態文件。

Flask使用了jinja2作為其html模板引擎,ToyWebF同樣使用jinja2,jinja2其實實現一種簡單的DSL(領域內語言),讓我們可以在HTML中通過特殊的語法改變HTML的結構,該項目非常值得研究學習。

首先 pip install jinja2 ,然後就可以使用它了,在ToyWebF項目目錄中創建templates目錄,以該目錄作為默認的HTML文件根目錄,代碼如下。

首先利用jinja2的FileSystemLoader類將file system中的某個文件夾作為loader,然後初始化Environment。

在使用的過程中(即調用template方法),通過get_template方法獲得具體的某個模板並通過render方法將對應的內容傳遞給模板中的變數。

這里我們不寫前端代碼,直接去互聯網中下載模板,這里下載了Bootstrap提供的免費模板,可以自行去 https://startbootstrap.com/themes/freelancer/ 下載,下載完後,你會獲得index.html以及對應的css、jss、img等文件,將index.html移動到ToyWebF/templates中並簡單修改了一下,添加一些變數。

然後在app.py文件中為index.html定義路由以及需要的參數。

至此html文件的支持就完成了,但此時的html無法正常載入css和js,導致頁面布局非常醜陋且交互無法使用。

接著就讓ToyWebF支持css、js,首先在ToyWebF目錄下創建static文件夾用於存放css、js或img等靜態文件,隨後直接將前面下載的模板,其中的靜態文件復制到static中則可。

通過whitenoise第三方庫,可以通過簡單的幾行代碼讓web框架支持css和js,不需要依賴nginx等服務,首先 pip install whitenoise ,隨後修改API類的 __init__ 方法,代碼如下。

其實就是通過WhiteNoise將self.wsgi_app方法包裹起來,在調用API的 __call__ 方法時,直接調用self.whitenoise。

此時,如果請求web服務獲取css、js等靜態資源,WhiteNoise會獲取其內容並返回給client,它在背後會匹配靜態資源在系統中對應的文件並將其讀取返回。

至此,一開始的網頁效果就實現好了。

web服務如果出現500時,默認會返回 internal server error ,這顯得比較丑,為了讓框架使用者可以自定義500時返回的錯誤,需要添加一些代碼。

首先API初始化時,初始self.exception_handler對象並定義對應的方法添加自定義的錯誤

在handler_request方法進行請求調度時,調度的方法執行邏輯時報500,此時不再默認將錯誤拋出,而是先判斷是否有自定義錯誤處理。

在app.py中,自定義錯誤返回方法,如下。

custom_exception_handler方法只返回自定義的一段話,你完全可以替換成美觀的template。

我們可以實驗性定義一個路由來看效果。

Web服務的中間件也可以理解成鉤子,即在請求前可以對請求做一些處理或者返回Response前對Response做一下處理。

為了支持中間件,在TopWebF目錄下創建middleware.py文件,在編寫代碼前,思考一下如何實現?

回顧一下現在請求的調度邏輯。

1.通過routes裝飾器關聯路由和方法 2.通過API.whitenoise處理 3.如果是請求API介面,那麼會將參數傳遞給API.wsgi_app 4.API.wsgi_app最終會調用API.handle_request方法獲取路由對應的方法並調用該方法執行相應的邏輯

如果希望在request前以及response後做相應的操作,那麼其實就需要讓邏輯在API.handle_request前後執行,看一下代碼。

其中add方法會實例化Middleware對象,該對象會將當前的API類實例包裹起來。

Middleware.handle_request方法其實就是在self.app.handle_request前調用self.process_request方法處理request前的數據以及調用self.process_response處理response後的數據,而核心的調度邏輯,依舊交由API.handle_request方法進行處理。

這里的代碼可能會讓人感到疑惑, __call__ 方法和handle_request方法中都有self.app.handle_request(request),但其調用對象似乎不同?這個問題暫時放一下,先繼續完善代碼,然後再回來解釋。

接著在api.py中為API創建middleware屬性以及添加新中間件的方法。

隨後,在app.py中,自定義一個簡單的中間件,然後調用add_middleware方法將其添加。

定義好中間件後,在請求調度時,就需要使用中間件,為了兼容靜態文件的情況,需要對css、js、ing文件的請求路徑做一下兼容,在其路徑中加上/static前綴

緊接著,修改API的 __call__ ,兼容中間件和靜態文件,代碼如下。

至此,中間件的邏輯就完成了。

但代碼中依舊有疑惑,Middleware類中的 __call__ 方法和handle_request方法其調用的self.app到底是誰?

為了方便理解,這里一步步拆解。

如果沒有添加新的中間件,那麼請求的調度邏輯如下。

在沒有添加中間件的情況下,self.app其實就是API本身,所以 middleware.__call__ 中的self.app.handle_request就是調用API.handle_request。

如果添加了新的中間件,如上述代碼中添加了名為SimpleCustomMiddleware的中間件,此時的請求調度邏輯如下。

因為注冊中間件時,Middleware.add方法替換了原始Middleware實例中的app對象,將其替換成了SimpleCustomMiddleware,而SimpleCustomMiddleware也有app對象,SimpleCustomMiddleware中的app對象,才是API類實例。

在請求調度的過程中,就會觸發Middleware類的handle_request方法,該方法就會執行中間件相應的邏輯去處理request和response中的數據。

當然,你可以通過Middleware.add方法添加多個中間件,這就會構成棧式調用的效果,代碼如下。

啟動web服務後,其執行效果如下。

⑵ Python的Flask框架中web表單


下面為你介紹了Python的Flask框架中判游web表單的教程,表單是學習各個web框架中的基礎知識,需要的朋友可以參考下
概要
在前面章節我們為主頁定義了一個簡單的模板,部分尚未實現的模塊如用戶或帖子等使用模擬的對象作為臨時佔位。
本章我們將看到如何利用web表單填補這些空白。
web表單是web應用中最基本的構建要素,我們將通過表單來實現用戶發帖和應用登錄功能。
完成本章內容你需要基於前面章節完成的微博應用代碼,請確認這些代碼已安裝並能正常運行。
配置
Flask-WTF是WTForms項目的Flask框架擴展,我們將用他來幫助我們處理web表單。
大部分Flask擴展都需要定義相關配置項,所以我們先來在應用根目錄下創建一個配置文件以備使用。我們先這樣創建 (fileconfig.py):
SRF_ENABLED = True
SECRET_KEY = you-will-never-guess
很簡單吧,這是Flask-WTF需要用到的2個配置項。CSRF_ENABLED配置啟用了跨站請求攻擊保護,大部分情況下你都需要開啟此功能,這能使你的應用更安全。
SECRET_KEY設置當CSRF啟用時有效,這將生成一個加密的token供表單驗證使用,你要確保這個KEY足夠復雜不會被簡單推測。
現在這個配置文件已經基本可用了。項目創建完成我們可以創建如下文件並編輯(fileapp/__init__.py):
?
from flask import Flask
app = Flask(__name__)
app.config.from_object(config)
from app import views
用戶登錄表單
使用Flask-WTF創建的表單就像一個對象,需要從Form類繼承子類。然後在這個子類中定義一些類的屬性變數作為表單欄位就可以了。
我們要創建一個登錄表單,用來進行用戶身份識別。但跟平常需要驗證用戶名和密碼的登錄方式不同,我們將使用 OpenId 來處理登錄過程。使用OpenId的好處就是我們不用管那些用戶名和密碼的認證過程,交給 OpenId 去搞定,它會返回給我們用戶驗證後的數據。這樣對於使用我們網站的用戶而言也更安全。
使用 OpenId 登錄只需要一個字元串,然後發送給 OpenId 伺服器就行了。另外我們還需要在表單中加一個「記住我」 的選項框,這個是送給那些不想每次來我們網站都要進行身份認證的人。選擇這個選項後,首次登錄時會用cookie在他們的瀏覽器上記住他們的登錄信息,下次再進入網站時就不需要進行登錄操作。
開始我們的第一個表單吧 (fileapp/forms.py):
?
from flask.ext.wtf import Form, TextField, BooleanField
from flask.ext.wtf import Required
class LoginForm(Form):
openid = TextField(openid, validators = [Required()])
remember_me = BooleanField(remember_me, default = False)
欣賞一下這個類,多麼的簡潔,多麼的一目瞭然。如此簡單,但又十分的富有內涵。我們引入了一個 Form 類,然後繼承這個類,按需求還添加了 TextField 和 BooleanField 這兩個欄位。
另外還引入了一個表單驗證函數 Required,這種驗證函數可以附加在欄位裡面,在用戶提交表單時它們會用來檢查用戶填寫的數據。這個 Required 函數是用來防止用戶提交空數據。Flask-WTF 中還有掘沖碧很多不同作用的表單驗證函數,我們將會在後面使用到它們。
表單模板
現在我們的問題就是需要一個顯示這個登錄表單的模板。好消息是我們剛剛創建的登錄表單類知道如何把欄位轉換成HTML,所以我們只需要把注意力集判舉中到頁面布局上。下面就是我們的登錄表單的模板 (fileapp/templates/login.html):
-- extend from base layout --
{% extends base.html %}
{% block content %}
h1Sign In/h1
form action= method=post name=login
{{form.hidden_tag()}}
p
Please enter your OpenID:br
{{form.openid(size=80)}}br
/p
p{{form.remember_me}} Remember Me/p
pinput type=submit value=Sign In/p
/form
{% endblock %}
容我_嗦一下,在這個模板中,我們又一次使用了模板繼承的方式。使用 extends 語句從 base.html 繼承模板內容。我們會在後面創建的模板中繼續使用這種方式,這樣可以使我們所有的頁面布局保持一致。
這個登錄模板跟普通的HTML表單有些明顯的區別,它使用模板參數 {{ ... }} 來實例化表單欄位,而表單欄位又來源於我們剛剛定義的表單類,模板參數中使用了 form 這個名稱。當我們使用視圖函數引用表單類並渲染到模板時,我們要特別注意這個把表單類傳遞到模板的變數名。
我們在配置中開啟了CSRF(跨站偽造請求)功能,模板參數 {{ form.hidden_tag() }} 會被替換成一個具有防止CSRF功能的隱藏表單欄位。在開啟了CSRF功能後,所有模板的表單中都需要添加這個模板參數。
我們定義的表單對象中的欄位同樣也能被模板渲染,只需要在模板合適的位置添加類似於 {{ form.field_name }} 這樣的模板參數,相關欄位就會在被定義的位置出現。另外還有一些欄位是可以傳參數,比如這個 openid 欄位,我們就添加了一個參數讓它顯示的寬度增加到80個字元。
由於我們沒有在表單中定義一個提交功能的按鈕,所以在這里只能以普通表單欄位的方式來做了。不過說起來區區一個按鈕,在表單中跟任何數據都沒有關系,的確也沒有在表單類中定義的必要。
表單視圖
見證奇跡的時刻最後一步,我們馬上要來寫一個渲染登錄表單對象到模板的視圖函數。
這個函數相當的簡單無趣,因為我們只需要把表單對象傳遞給模板就行了。下面就是我們這個視圖函數的全部內容 (fileapp/views.py):
11
12
from flask import render_template, flash, redirect
from app import app
from forms import LoginForm
# index view function suppressed for brevity
@app.route(/login, methods = [GET, POST])
def login():
form = LoginForm()
return render_template(login.html,
title = Sign In,
form = form)
我們引入登錄表單類,然後把它實例化到一個變數,最後再把這個變數傳給模板。要渲染表單欄位必須的事情也就這些。
上面的代碼中還引入了兩個新對象: falsh 和 redirect, 這個先甭理它們,稍後才用得上。
另外還做了一件事就是在路由裝飾器中添加一個新方法。讓 Flask 明白我們這個視圖函數支持 GET 和 POST 請求。否則這個視圖函數只會響應 GET 請求。我們需要得到用戶填寫表單後提交的數據,這些數據是從 POST 請求中傳遞過來的。
你可以通過在瀏覽器中測試這個程序來了解上面所說的。 按照視圖函數關聯的路由,你應該在瀏覽器中輸入
由於我們還沒有寫任何接收數據的代碼,所以現在你在頁面中點提交按鈕還沒有任何效果。
從表單中接收數據
另外值得一提的是, Flask-WTF 對表單提交數據的處理使我們的接下來要做的事情變得簡單了。下面就是我們這個登錄視圖函數的新版本, 加入了表單數據驗證和處理 (fileapp/views.py):
?
7
8
9
@app.route(/login, methods = [GET, POST])
def login():
form = LoginForm()
if form.validate_on_submit():
flash(Login requested for OpenID= + form.openid.data + , remember_me= + str(form.remember_me.data))
return redirect(/index)
return render_template(login.html,
title = Sign In,
form = form)
validate_on_submit() 這個方法做了表單處理的所有工作。如果你在表單向用戶提供數據時(舉個栗子:用戶在它之前修改了一下提交的數據) 時調用此方法,它會返回 False。發生這樣的情況時,你懂的。不懂?就是提交的數據驗證不通過,你要繼續渲染模板。
在提交請求時調用了表單的 validate_on_submit() 方法後,它會從請求中獲取所有提交的數據,然後使用表單欄位中綁定的驗證函數進行數據驗證。在所有的數據都驗證通過時會返回 True. 這就意味著你可以放心的使用這些表單數據了。
只要有一個欄位驗證不通過,它都會返回 False. 這時就需要我們返回數據給用戶,讓他們來糾正一下錯誤數據。接下來我們將會看到在數據驗證失敗時,如何把錯誤消息顯示給用戶。
當 validate_on_submit() 方法返回 True 的時候,我們的視圖函數又會調用兩個新的函數。它們都是從Flask 中引入的,flash 函數用來在下一個打開的頁面中顯示定義的消息。我們現在用它用來做調試。因為我們現在還沒有做用戶登錄模塊, 所以只需要把用戶提交上來的數據顯示一下就行了。flash 函數非常有用,比如為用戶的一些操作提供消息反饋。
flash 函數提供的消息不會自動出現在我們的網站頁面中,所以我們需要做點事情讓它在頁面中顯示出來。為了讓我們所有頁面都能有這項激動人心的功能,所以就把它添加到基礎模板中吧, 下面是更新後的基礎模板 (fileapp/templates/base.html):
html
head
{% if title %}
title{{title}} - microblog/title
{% else %}
titlemicroblog/title
{% endif %}
/head
body
divMicroblog: a href=/indexHome/a/div
hr
{% with messages = get_flashed_messages() %}
{% if messages %}
ul
{% for message in messages %}
li{{ message }} /li
{% endfor %}
/ul
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
/body
/html
模板中顯示 flash 消息的功能希望你能明白。
在視圖函數中我們使用的另一個新函數就是 redirect. 這個函數會通知用戶的瀏覽器跳轉到指定的地址。在我們的視圖函數中,我們使用它跳轉到了首頁。注意跳轉結束後頁面上還會顯示 flash 函數傳遞的消息哦。
激動人心的時刻到了,運行我們的程序吧,看看錶單是如何工作的吧。不要填寫表單中的 openid 欄位,看看 Required 這個驗證函數是如何發揮威力,把一切發起空數據的請求阻止在千里之外。
改善一下欄位驗證
我們程序目前狀況不錯,提交不合要求的數據會被阻止,還會返回表單讓用戶修改,基本滿足我們要求。
但似乎還少點什麼。如果我們在用戶提交數據失敗後給用戶點提示,讓他們知道什麼原因引起的,豈不妙哉!太幸運了,用 Flask-WTF 可以輕松解決這個問題。
當表單欄位驗證失敗時, Flask-WTF 會添加一個錯誤消息到表單對象。這些消息在模板中也是可以使用的,所以我們只需要在模板中添加一點點東西就OK了。
這個就是我們添加了驗證消息的登錄模板 (fileapp/templates/login.html):
16
17
18
!-- extend base layout --
{% extends base.html %}
{% block content %}
h1Sign In/h1
form action= method=post name=login
{{form.hidden_tag()}}
p
Please enter your OpenID:br
{{form.openid(size=80)}}br
{% for error in form.errors.openid %}
span style=color: red;[{{error}}]/span
{% endfor %}br
/p
p{{form.remember_me}} Remember Me/p
pinput type=submit value=Sign In/p
/form
{% endblock %}
我們僅在 openid 欄位的右邊添加了一個循環語句,它會把openid欄位驗證失敗的消息都顯示出來。不論你的表單有多少欄位,所有表單欄位驗證失敗的錯誤消息都可以用 form.errors.欄位名 這種方式來使用。這個表單中我們的是 form.errors.openid。為了讓錯誤消息引起用戶的注意,我們還給消息添加了顯示紅色的 css 樣式。
處理 OpenID 登錄
現實生活中,我們發現有很多人都不知道他們擁有一些公共賬號。一部分大牌的網站或服務商都會為他們的會員提供公共賬號的認證。舉個栗子,如果你有一個 google 賬號,其實你就有了一個公共賬號,類似的還有 Yahoo, AOL, Flickr 等。
為了方便我們的用戶能簡單的使用他們的公共賬號,我們將把這些公共賬號的鏈接添加到一個列表,這樣用戶就不用自手工輸入了。
我們要把一些提供給用戶的公共賬號服務商定義到一個列表裡面,這個列表就放到配置文件中吧 (fileconfig.py):
?
7
8
9
CSRF_ENABLED = True
SECRET_KEY = you-will-never-guess
OPENID_PROVIDERS = [
{ name: Google, url:
{ name: Yahoo, url:
{ name: AOL, url:
{ name: Flickr, url:
{ name: MyOpenID, url:
}]
接下來就是要在我們的登錄視圖函數中使用這個列表了:
@app.route(/login, methods = [GET, POST])
def login():
form = LoginForm()
if form.validate_on_submit():
flash(Login requested for OpenID= + form.openid.data + , remember_me= + str(form.remember_me.data))
return redirect(/index)
return render_template(login.html,
title = Sign In,
form = form,
providers = app.config[OPENID_PROVIDERS])
我們從 app.config 中引入了公共賬號服務商的配置列表,然後把它作為一個參數通過 render_template 函數引入到模板。
接下來要做的我想你也猜得到,我們需要在登錄模板中把這些服務商鏈接顯示出來。
24
25
26
27
28
29
30
31
32
33
34
!-- extend base layout --
{% extends base.html %}
{% block content %}
script type=text/javascript
function set_openid(openid, pr)
{
u = openid.search(username)
if (u != -1) {
// openid requires username
user = prompt(Enter your
+ pr +
username:)
openid = openid.substr(0, u) + user
}
form = document.forms[login];
form.elements[openid].value = openid
}
/script
h1Sign In/h1
form action= method=post name=login
{{form.hidden_tag()}}
p
Please enter your OpenID, or select one of the providers below:br
{{form.openid(size=80)}}
{% for error in form.errors.openid %}
span style=color: red;[{{error}}]/span
{% endfor %}br
|{% for pr in providers %}
a href=javascript:set_openid({{pr.url}}, {{pr.name}});{{pr.name}}/a |
{% endfor %}
/p
p{{form.remember_me}} Remember Me/p
pinput type=submit value=Sign In/p
/form
{% endblock %}
這次的模板添加的東西似乎有點多。一些公共賬號需要提供用戶名,為了解決這個我們用了點 javascript。當用戶點擊相關的公共賬號鏈接時,需要用戶名的公共賬號會提示用戶輸入用戶名, javascript 會把用戶名處理成可用的公共賬號,最後再插入到 openid 欄位的文本框中。
下面這個是在登錄頁面點擊 google 鏈接後顯示的截圖:

⑶ 在Python中使用HTML模版的教程


這篇文章主要介紹了在Python中使用HTML模版的教程,HTML模版也是Python的各大框架下的一個基本功能,需要的朋友可以參考下。Web框架把我們從WSGI中拯救出來了。現在,我們只需要不斷地編寫函數,帶上URL,就可以繼續Web App的開發了。
但是,Web App不僅僅是處理邏輯,展示給用戶的頁面也非常重要。在函數中返回一個包含HTML的字元串,簡單的頁面還可以,但是,想想新浪首頁的6000多行的HTML,你確信能在Python的字元串中正確地寫出來么?反正我是做不到。
俗話說得好,不懂前端的Python工程師不是好的產品經理。有Web開發經驗的同學都明白,Web App最復雜的部分就在HTML頁面。HTML不僅要正確,還要通過CSS美化,再加上復雜的JavaScript腳本來實現各種交互和動畫效果。總之,生成HTML頁面的難度很大。
由於在Python代碼里拼字元串是不現實的,所以,模板技術出現了。
使用模板,我們需要預先准備一個HTML文檔,這個HTML文檔不是普通芹腔的HTML,而是嵌入了一些變數和指令,然後,根據我們傳入的數據,替換後嫌嫌衫,得到最終的HTML,發送給用戶:
這就是傳說中的MVC:Model-View-Controller,中文名「模型-視圖-控制器」。
Python處理URL的函數就是C:Controller,Controller負責業務邏輯,比如檢查用戶名是否存在,取出用戶信息等等;
包含變數{{ name }}的模板就是V:View,View負責顯示邏者枝輯,通過簡單地替換一些變數,View最終輸出的就是用戶看到的HTML。
MVC中的Model在哪?Model是用來傳給View的,這樣View在替換變數的時候,就可以從Model中取出相應的數據。
上面的例子中,Model就是一個dict:
{ name: Michael }
只是因為Python支持關鍵字參數,很多Web框架允許傳入關鍵字參數,然後,在框架內部組裝出一個dict作為Model。
現在,我們把上次直接輸出字元串作為HTML的例子用高端大氣上檔次的MVC模式改寫一下:
16
17
18
19
20
21
22
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()函數來實現模板的渲染。和Web框架類似,Python的模板也有很多種。Flask默認支持的模板是jinja2,所以我們先直接安裝jinja2:
?
1
$ easy_install jinja2
然後,開始編寫jinja2模板:
?
1
home.html
用來顯示首頁的模板:
11
html
head
titleHome/title
/head
body
h1 style=font-style:italicHome/h1
/body
/html
form.html
用來顯示登錄表單的模板:
16
17
18
html
head
titlePlease Sign In/title
/head
body
{% if message %}
p style=color:red{{ message }}/p
{% endif %}
form action=/signin method=post
legendPlease sign in:/legend
pinput name=username placeholder=Username value={{ username }}/p
pinput name=password placeholder=Password type=password/p
pbutton type=submitSign In/button/p
/form
/body
/html
signin-ok.html
登錄成功的模板:
?
7
8
html
head
titleWelcome, {{ username }}/title
/head
body
pWelcome, {{ username }}!/p
/body
/html
登錄失敗的模板呢?我們在form.html中加了一點條件判斷,把form.html重用為登錄失敗的模板。
最後,一定要把模板放到正確的templates目錄下,templates和app.py在同級目錄下:
啟動python app.py,看看使用模板的頁面效果:
通過MVC,我們在Python代碼中處理M:Model和C:Controller,而V:View是通過模板處理的,這樣,我們就成功地把Python代碼和HTML代碼最大限度地分離了。
使用模板的另一大好處是,模板改起來很方便,而且,改完保存後,刷新瀏覽器就能看到最新的效果,這對於調試HTML、CSS和JavaScript的前端工程師來說實在是太重要了。
在Jinja2模板中,我們用{{ name }}表示一個需要替換的變數。很多時候,還需要循環、條件判斷等指令語句,在Jinja2中,用{% ... %}表示指令。
比如循環輸出頁碼:
?
1
2
3
{% for i in page_list %}
a href=/page/{{ i }}{{ i }}/a
{% endfor %}
如果page_list是一個list:[1, 2, 3, 4, 5],上面的模板將輸出5個超鏈接。
除了Jinja2,常見的模板還有:
Mako:用和${xxx}的一個模板;
Cheetah:也是用和${xxx}的一個模板;
Django:Django是一站式框架,內置一個用{% ... %}和{{ xxx }}的模板。
小結
有了MVC,我們就分離了Python代碼和HTML代碼。HTML代碼全部放到模板里,寫起來更有效率。

⑷ 使用python創建web靜態網站

打開pyCharm企業版軟體,創建一個Django項目,其中Django是一個Web框架,用於幫助開發互動式網站的工具。生成項目文件如下圖所示:

在url.py文件中添加為:

在view.py文件中添加:

在templates文件夾中新建index.html文件

其中<a>為超鏈接標簽,在此使用了一個模板標簽,是用大括弧和百分號({% %})表示的。{% url 'namespacename:index' %}是一個模板標簽,指向url.py中index的URL模式匹配。在這個實例中,namespacename是對應的命名空間名稱,index是URL模式。

⑸ Python 有哪些好的 Web 框架

1、Django框架
優點:是一個高層次Python Web開發框架,特點是開發快速、代碼較少、可擴展性強。Django採用MTV(Model、Template、View)模型組織資源,框架功能豐富,模板擴展選擇最多。對於專業人員來說,Django是當之無愧的Python排名第一的Web開發框架。
缺點:包括一些輕量級應用不需要的功能模塊,不如Flask輕便。過度封裝很多類和方法,直接使用比較簡單,但改動起來比較困難。相比於 C,C++性能,Django性能偏低。模板實現了代碼和樣式完全分離,不允許模板里出現Python代碼,靈活度不夠。另外學習曲線也相對陡峭。
2、Flask框架
優點:Flask是一個Python Web開發的微框架,嚴格來說,它僅提供Web伺服器支持,不提供全棧開發支持。然而,Flask非常輕量、非常簡單,基於它搭建Web系統都以分鍾來計時,特別適合小微原型系統的開發。花少時間、產生可用系統,是非常劃算的選擇。
缺點:對於大型網站開發,需要設計路由映射的規則,否則導致代碼混亂。對新手來說,容易使用低質量的代碼創建 「不良的web應用程序」。
3、Pyramid框架
優點:是一個擴展性很強且靈活的Python Web開發框架。上手十分容易,比較適合中等規模且邊開發邊設計的場景。Pyramid不提供絕對嚴格的框架定義,根據需求可以擴展開發,對高階程序員十分友好。
缺點:國內知名度不高,高級用法需要通過閱讀源代碼獲取靈感。默認使用Chameleon模板,靈活度沒有成為一個要素。
4、web.py框架
優點:正如其名,web.py是一個採用Python作為開發語言的Web框架,簡單且強大。俄羅斯排名第一的Yandex搜索引擎基於這個框架開發,Guido van Rossum認為這是最好的Python Web框架,還需要說別的嗎?有事實作證、有大牛認可,用起來吧!
缺點:Web.py並未像其他框架一樣保持與Python 3兼容性的最新狀態。這不僅意味著缺乏對非同步語法的支持,還意味著缺少對已棄用的函數的錯誤。此外,目前尚不清楚維護者是否有計劃在Python 2到達其支持生命周期結束後保持Web.py的最新狀態。
5、Tornado框架
優點:Tornado是一個基於非同步網路功能庫的Web開發框架,因此,它能支持幾萬個開放連接,Web服務高效穩定。可見,Tornado適合高並發場景下的Web系統,開發過程需要採用Tornado提供的框架,靈活性較差,確定場景後再考慮使用不遲。
缺點:Tornado 5.0改進了與Python的本機非同步功能的集成。因此不再支持Python 3.3.並且Python 3.5用戶必須使用Python 3.5.2或更高版本。Tornado 6.0將需要Python 3.5及更高版本,並將完全放棄Python 2支持。

熱點內容
androidurl獲取圖片 發布:2025-02-07 02:22:11 瀏覽:482
調用上傳 發布:2025-02-07 02:19:53 瀏覽:84
aix編譯安裝 發布:2025-02-07 02:19:52 瀏覽:906
android界面設計尺寸 發布:2025-02-07 02:16:25 瀏覽:898
zenly安卓為什麼會一直閃 發布:2025-02-07 02:12:02 瀏覽:357
為什麼安卓手機界面總出廣告 發布:2025-02-07 02:10:33 瀏覽:243
plc數據塊怎麼編譯 發布:2025-02-07 02:09:44 瀏覽:98
ct加密 發布:2025-02-07 02:09:03 瀏覽:919
編程差別 發布:2025-02-07 02:06:37 瀏覽:348
pythonmysqlmac安裝 發布:2025-02-07 01:56:36 瀏覽:403