沒看form有關(guān)的源碼,但是應(yīng)該是這樣的∶
成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比安州網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式安州網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋安州地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
首先,你得理解像flask這種MVC(或者說MTC)的基本運(yùn)行機(jī)制。
- 對(duì)于flask的view,你得知道wsgi協(xié)議(如果不清楚,請(qǐng)自行Google之)。
更底層(邏輯上的底層)的HTTP utils(flask用的是werkzeug)將client端的HTTP requests等進(jìn)行parse,并且將其構(gòu)建為wsgi的environment(包含了request及其他信息)。
wsgi
server在process請(qǐng)求的過程是:根據(jù)wsgi協(xié)議構(gòu)建environ,將其傳入flask app
instance(這個(gè)即為flask框架實(shí)現(xiàn)的wsgi app),flask app
instance用這個(gè)environ和自己的``start_response``
method(這個(gè)也是uwsgi協(xié)議規(guī)約)完成請(qǐng)求處理并response。
flask有一個(gè)線程級(jí)(或greenlet)的request對(duì)象。在真正process response之前,將environ丟到這個(gè)request對(duì)象里,之后這個(gè)request跟著你的那個(gè)線程就成為了默契的炮友~~直至response完成或線程完蛋。
views里面的那一坨坨的route的作用是啥捏?這個(gè)就是url routing了,就是我在你的站點(diǎn)上點(diǎn)了一個(gè)特定的url,flask要如何滿足你。你得說出你想要的東西吧。
那么views是什么時(shí)候用到呢?廢話,當(dāng)然還是在接收并理解請(qǐng)求之后到響應(yīng)之前。
好
了,flask app instance在處理你的需求的時(shí)候從request對(duì)象里拿到了你請(qǐng)求的url,這個(gè)就相當(dāng)于一把key,然后app
instance根據(jù)這個(gè)key去views里找到了對(duì)應(yīng)的鎖(你想要的處理邏輯,就是views里的route下面的function),這個(gè)鎖啊,她
一旦被打開了,滿足你需求的時(shí)刻也就快了 ~ ~
P.S. 至于如何匹配到這個(gè)鎖的呢,這個(gè)就是url mapping了,就是一堆正則匹配(別小看這個(gè),如果你用過flask的blueprint,你會(huì)明白寫這么個(gè)mapping也是件爽hi了的事情咯)
- model controller呢?
你的需求其實(shí)就是要flask給你response,response其實(shí)呢就是數(shù)據(jù)(不管是RESTFUL API還是template形式,都是你擼出的data)。
數(shù)據(jù)這坨翔實(shí)怎么來的呢?就是你從數(shù)據(jù)庫(廣義,包括sql nosql db,內(nèi)存級(jí)緩存,磁盤文件等等等等)拿到的,至于data的來源嘛,可能是你自己插的,或者是從別的地方哭著要來的。
model
就是干這活的,只不過它比較抽象,將數(shù)據(jù)庫操作轉(zhuǎn)成了對(duì)Python對(duì)象的操作(這個(gè)就是大名鼎鼎的ORM,其實(shí)并沒有什么卵用,ORM寫多了你連查詢優(yōu)
化都忘了,如果你有比較高的performance需求也有很多時(shí)間,就自己擼高效檢索方案吧,我沒少被這玩意兒坑%_%)。
controller這玩意兒你其實(shí)可以不要,不過為了做邏輯分離,讓你擼業(yè)務(wù)擼的漂亮點(diǎn)兒還是用它吧。
OK,說了這么多,不知道有沒有人能看懂,如果沒看懂,讓我思考會(huì)兒吧 ~ ~
========================================================================
簡(jiǎn)而言之呢,你用flask作application的時(shí)候,MVC各司其職堆好你產(chǎn)生data的邏輯即可,其它你一概不用管。
靠,終于可以回到你的問題上了:
先看下Form這玩意兒:
from flask.ext.wtf import Form
from wtforms import StringField, SubmitField
from wtforms.validators import Required
class NameForm(Form):
name = StringField('What is your name?', validators=[Required()])
submit = SubmitField('Submit')
這就是一個(gè)類而已,和model里面的那些玩意兒沒本質(zhì)區(qū)別,也都是一個(gè)映射關(guān)系。model是將數(shù)據(jù)庫啥的和Python對(duì)象映射;Form是將HTML表單(form)和這個(gè)從flask.ext.wtf.Form及其子類映射。
再來看看這玩意兒:
1 @app.route('/', methods=['GET', 'POST'])
2 def index():
3 name = None
4 form = NameForm()
5 if form.validate_on_submit():
6 name = form.name.data
7 form.name.data = ''
8 return render_template('index.html', form=form, name=name)
首先來分析一下執(zhí)行過程:
哎呀,這個(gè)只是個(gè)route嘛,它哪有執(zhí)行過程。
執(zhí)行是由app instance做的嘛,好吧,其實(shí)它是被app instance做的。
在
展開之前看一下route后面那個(gè) methods=['GET',
'POST']。這玩意的意思是說,當(dāng)我遇到有與``index``(即上面route下面的那個(gè)index)匹配的的請(qǐng)求時(shí),我可以用GET或者
POST方法,其他的像PUT、DELETE等HTTP verb我不讓你丫玩兒。
當(dāng)你把你的這個(gè)flask應(yīng)用deploy到web server或者在本地run test server的時(shí)候,你在瀏覽器里輸入 的時(shí)候,你向server發(fā)射的是``GET``炮彈,flask instance接受了你的彈,然后route到了index這個(gè)函數(shù),好吧,激動(dòng)人心的時(shí)刻到了:
#3. name = None 這個(gè)就是個(gè)賦值
#4. form = NameForm() 好吧,這個(gè)就是NameForm類的實(shí)例化,拿到一個(gè)form object。
#5.
if form.validate_on_submit(): 呵呵,這個(gè)嘛,意思是問一下#2中實(shí)例化的form
object,SB,你是在被人(1)submit(提交)并且(2)提交滿足我的要求么?
好吧,前面說過了,我是在GET,而沒有在submit(submit在HTML中為POST),好吧,我連(1)都不滿足,所以也就沒有#6、#7什么
事兒了。
#8 好的,app instance終于快要向你回饋了。給我把前面的from object和name變量一起帶到index.html這個(gè)文件里吧。
哈哈,終于有jinja2的活兒了,@題主, 你丫也把index.html發(fā)上來呀 = =
index.html
里你寫了個(gè)表單,里面有個(gè)叫做``name``的field和一個(gè)``submit``按鈕,這些field和你的``NameForm``對(duì)應(yīng),好了,
對(duì)應(yīng)填充的活兒和就交給jinja2吧,它會(huì)給你一個(gè)最終將在用戶瀏覽器顯示的index.html。
view的使命完成了,它成功的生成了數(shù)據(jù)。
app instance 拿到了view的數(shù)據(jù),也該向client端發(fā)最終響應(yīng)了。OK,server完成了這次request的response,用戶拿到最終想要的東西了。
瀏覽器或者UA干的活兒我就不展開了,我的手已經(jīng)抽筋了,
現(xiàn)在在用戶的瀏覽器上,看到了index.html,上面有一個(gè)表單,那個(gè)表單上面有個(gè)文本框(有``What is your name?``的placeholder)和一個(gè)Submit提交按鈕。
好
了,用戶在那個(gè)文本框中寫了一個(gè)名字,比如``John``,然后按了那個(gè)``Submit``按鈕,這次提交回向server發(fā)射一個(gè)``POST``
請(qǐng)求,這個(gè)請(qǐng)求里面會(huì)帶上文本框的名字(哈哈,就是name)和文本框name里面的值(yeah,就是``John``)。然后呢,到flask
instance中,request對(duì)象(如果不知道這是什么東西,看前文)里就會(huì)有所有這些有關(guān)請(qǐng)求的數(shù)據(jù)了。
辣么,辣么這跟from有毛線關(guān)系呢????
其實(shí)吧,form中的數(shù)據(jù)是flask從request(request是從environ構(gòu)建的)中拿到并映射進(jìn)form屬性中的(映射過程發(fā)生在你實(shí)例化form的時(shí)候),這個(gè)過程我也不展開了。好吧,不知道有沒有解釋你
name = form.name.data
為什么會(huì)有數(shù)據(jù)的疑問。
我實(shí)在不想在打字了,好累噢!!?。?!
好
吧,總結(jié)起來就是,HTTP utils將用戶的raw request解析成符合wsgi規(guī)范的environ,然后flask
instance將environ丟到線程級(jí)的request
object里,在你實(shí)例化flask.ext.wtf.Form及其子類時(shí),會(huì)從request object里解析并映射數(shù)據(jù)到form中。
關(guān)于讀書的話,如果你覺得你實(shí)在看不明白,那可能是有關(guān)web底層一點(diǎn)的知識(shí)稍微欠缺,可以補(bǔ)補(bǔ)這塊的知識(shí),對(duì)于框架的處理機(jī)制,最好的辦法是 看?。?!源?。。。〈a?。。。?!
看不懂就補(bǔ)基礎(chǔ),如此而已。
上面過程都是我信手打出來的,也好久沒用flask了,寫的時(shí)候也沒查資料,如有bug或建議可以告訴我,以便我修改。
flask本身相當(dāng)于一個(gè)內(nèi)核,幾乎其他所有的功能都要用到擴(kuò)展:郵件擴(kuò)展Flask-Mail,用戶認(rèn)證Flask-Login,數(shù)據(jù)庫Flask-SQLAIchemy等,都需要用第三方擴(kuò)展來實(shí)現(xiàn)。flask沒有默認(rèn)使用的數(shù)據(jù)庫,可以根據(jù)自己的選擇MySQL或者nosql。其WSGI工具箱采用Werkzeug的路由模塊,模板引擎則使用jinjia2。這兩個(gè)也是flask框架的核心。
常用擴(kuò)展
框架對(duì)比:
總結(jié):至于選什么框架-輕重對(duì)比-框架選擇上:
flask:后期業(yè)務(wù)升級(jí)迭代,更換技術(shù)方案,自由,靈活,高度定制。
Django:快速實(shí)現(xiàn)業(yè)務(wù),不考慮技術(shù)選型,越簡(jiǎn)單直接越好。
Tornado:tornado走的是少而精的方向,注重的是性能優(yōu)越,它最突出的是異步非阻塞的設(shè)計(jì)方式:HTTP服務(wù)器,異步編程,websockets。
(1)Flask
Flask確實(shí)很“輕”,不愧是Micro Framework,從Django轉(zhuǎn)向Flask的開發(fā)者一定會(huì)如此感慨,除非二者均為深入使用過
Flask自由、靈活,可擴(kuò)展性強(qiáng),第三方庫的選擇面廣,開發(fā)時(shí)可以結(jié)合自己最喜歡用的輪子,也能結(jié)合最流行最強(qiáng)大的Python庫
入門簡(jiǎn)單,即便沒有多少web開發(fā)經(jīng)驗(yàn),也能很快做出網(wǎng)站
非常適用于小型網(wǎng)站
非常適用于開發(fā)web服務(wù)的API
開發(fā)大型網(wǎng)站無壓力,但代碼架構(gòu)需要自己設(shè)計(jì),開發(fā)成本取決于開發(fā)者的能力和經(jīng)驗(yàn)
各方面性能均等于或優(yōu)于Django
Django自帶的或第三方的好評(píng)如潮的功能,F(xiàn)lask上總會(huì)找到與之類似第三方庫
Flask靈活開發(fā),Python高手基本都會(huì)喜歡Flask,但對(duì)Django卻可能褒貶不一
Flask與關(guān)系型數(shù)據(jù)庫的配合使用不弱于Django,而其與NoSQL數(shù)據(jù)庫的配合遠(yuǎn)遠(yuǎn)優(yōu)于Django
Flask比Django更加Pythonic,與Python的philosophy更加吻合
(2)Django
Django太重了,除了web框架,自帶ORM和模板引擎,靈活和自由度不夠高
Django能開發(fā)小應(yīng)用,但總會(huì)有“殺雞焉用牛刀”的感覺
Django的自帶ORM非常優(yōu)秀,綜合評(píng)價(jià)略高于SQLAlchemy
Django自帶的模板引擎簡(jiǎn)單好用,但其強(qiáng)大程度和綜合評(píng)價(jià)略低于Jinja
Django自帶ORM也使Django與關(guān)系型數(shù)據(jù)庫耦合度過高,如果想使用MongoDB等NoSQL數(shù)據(jù),需要選取合適的第三方庫,且總感覺Django+SQL才是天生一對(duì)的搭配,Django+NoSQL砍掉了Django的半壁江山
Django目前支持Jinja等非官方模板引擎
Django自帶的數(shù)據(jù)庫管理app好評(píng)如潮
Django非常適合企業(yè)級(jí)網(wǎng)站的開發(fā):快速、靠譜、穩(wěn)定
Django成熟、穩(wěn)定、完善,但相比于Flask,Django的整體生態(tài)相對(duì)封閉
Django是Python web框架的先驅(qū),用戶多,第三方庫最豐富,最好的Python庫,如果不能直接用到Django中,也一定能找到與之對(duì)應(yīng)的移植
Django上手也比較容易,開發(fā)文檔詳細(xì)、完善,相關(guān)資料豐富
Flask 是一種具有平緩學(xué)習(xí)曲線和龐大社區(qū)支持的微框架,利用它可以構(gòu)建大規(guī)模的web應(yīng)用。是搭建社區(qū)平臺(tái)的神器之一。 利用它可以構(gòu)建大規(guī)模的web應(yīng)用。學(xué)習(xí)上手Flask非常輕松,但要深入理解卻并不容易。本書從一個(gè)簡(jiǎn)單的Flask應(yīng)用開始,通過解決若干實(shí)戰(zhàn)中的問題,對(duì)一系列進(jìn)階的話題進(jìn)行了探討。書中使用MVC(模型-視圖-控制器)架構(gòu)對(duì)示例應(yīng)用進(jìn)行了轉(zhuǎn)化重構(gòu),以演示如何正確地組織應(yīng)用代碼結(jié)構(gòu)。有了可擴(kuò)展性強(qiáng)的應(yīng)用結(jié)構(gòu)之后,接下來的章節(jié)使用Flask擴(kuò)展為應(yīng)用提供了額外的功能,包括用戶登錄和注冊(cè)、NoSQL查詢、REST API、一套后臺(tái)管理界面,以及其他特性。然后,你會(huì)學(xué)到如何使用單元測(cè)試,保障代碼持續(xù)按照正確的方式工作,避免極具風(fēng)險(xiǎn)的猜測(cè)式編程。 一個(gè)簡(jiǎn)單的Flask 項(xiàng)目入手,由淺入深地探討了一系列實(shí)戰(zhàn)問題,包括如何使用SQLAlchemy 和Jinja 等工具進(jìn)行Web 開發(fā);如何正確地設(shè)計(jì)擴(kuò)展性強(qiáng)的Flask 應(yīng)用架構(gòu)和搭建MVC 環(huán)境;對(duì)于各種NoSQL 數(shù)據(jù)庫的特性,何時(shí)應(yīng)該、何時(shí)不應(yīng)該及如何使用它們;通過使用Flask 擴(kuò)展快速實(shí)現(xiàn)用戶的身份系統(tǒng)、RESTful API、NoSQL查詢、后臺(tái)管理等功能;如何創(chuàng)建自己的擴(kuò)展;使用Celery 編寫異步任務(wù),使用pytest 進(jìn)行單元測(cè)試等;最后介紹了如何部署上線,包括使用自己搭建的服務(wù)器或使用各種云服務(wù),以及如何權(quán)衡和選擇這些不同的解決方案。
InternetExplorer(包含傲游,世界之窗等和IE使用同一內(nèi)核的瀏覽器) 工具-Internet 選項(xiàng)-瀏覽歷史記錄一欄點(diǎn)“設(shè)置”-查看文件
瀏覽器自動(dòng)打開了IE的緩存文件夾(臨時(shí)文件夾)。