pkyx是一個(gè)用Flask+MongoDB開發(fā)" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

18143453325 在線咨詢 在線咨詢
18143453325 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運(yùn)營 > Flask 10天開發(fā)一個(gè)網(wǎng)站

Flask 10天開發(fā)一個(gè)網(wǎng)站

時(shí)間:2022-08-30 17:15:01 | 來源:網(wǎng)站運(yùn)營

時(shí)間:2022-08-30 17:15:01 來源:網(wǎng)站運(yùn)營

偶然找到一篇兩年半前大二時(shí)寫的文章,記錄了十天內(nèi)是怎么完成一個(gè)網(wǎng)站的,很多內(nèi)容現(xiàn)在看起來都過時(shí)了,文風(fēng)和代碼也有各種槽點(diǎn)(切勿模仿!),但還是想發(fā)布出來,畢竟記錄了一個(gè)曾經(jīng)奮斗的自己:)


pkyx是一個(gè)用Flask+MongoDB開發(fā)的比較(維基)網(wǎng)站。

Day 1:配置遠(yuǎn)程開發(fā)環(huán)境

首先在 Paralles Desktop下安裝了64位的Ubuntu 15.04版本,里面配置了nginx和virtualenv。

1.在Ubuntu中新建一個(gè)目錄,用virtualenv創(chuàng)建好虛擬環(huán)境,用pip安裝flask,接著測(cè)試一下。

2.在Pycharm下新建一個(gè)項(xiàng)目,編譯器選擇虛擬機(jī)中用virtualenv里的python解釋器。

3.在虛擬機(jī)中使用ifconfig命令查看ip地址,然后配置好ssh的選項(xiàng),連接前記得已經(jīng)在虛擬機(jī)中安裝好ssh-server,因?yàn)槟J(rèn)它是只有ssh-client而沒有ssh的服務(wù)器的,用apt-get install openssh-server安裝之,用戶和密碼為虛擬機(jī)中的用戶名和密碼。

3.創(chuàng)建好項(xiàng)目后,在Tools-Deployment-Configuation中配置sftp選項(xiàng),在這里要注意Root Path是指在遠(yuǎn)程主機(jī)(ubuntu)中的頂層路徑。

在Mapping選項(xiàng)卡中,配置項(xiàng)目路徑映射到遠(yuǎn)程主機(jī)的項(xiàng)目路徑。

4.在Tools-Deployment-Option中配置Upload changed files automatically to the default server。這里是選擇host的項(xiàng)目和遠(yuǎn)程主機(jī)項(xiàng)目的同步時(shí)刻,Always是一直保持同步,Ctrl+s是指保存時(shí)同步。

5.編寫代碼,這里寫了一個(gè)返回hello world的路由。

6.把代碼同步到遠(yuǎn)程主機(jī)上,Upload to直接把代碼推送到虛擬機(jī)的項(xiàng)目路徑中,Sync with Deployed to..查看項(xiàng)目部署的文件狀態(tài)和選擇同步的文件。

到這里基本上配置已經(jīng)算完成了,下面直接Run運(yùn)行代碼。

7.運(yùn)行代碼。

可以看到,flask的程序已經(jīng)開始啟動(dòng),但是這里要注意,在本機(jī)是不能夠直接訪問虛擬機(jī)上的localhost的,所以這里的http://127.0.0.1:5000/是指在虛擬機(jī)的服務(wù),而在host這邊是無法通過此路徑查看的。那怎么辦?之前我們說過在虛擬機(jī)中配置了nginx,此時(shí)它的作用就來了,總所周知,nginx的其中一個(gè)常見用途就是作反向代理,于是,在這里我們也用nginx代理flask程序。

(其實(shí)這里也有另外一種方法,就是在Paralles中的網(wǎng)絡(luò)設(shè)置里面配置端口映射,這樣就有辦法在host主機(jī)中訪問到虛擬機(jī)的localhost了。)

8.修改nginx配置文件(/etc/nginx/site-available/[conf])。

我們的nginx服務(wù)器監(jiān)聽了虛擬機(jī)的80端口,把跟路徑的request轉(zhuǎn)發(fā)到flask綁定的5000端口,而靜態(tài)文件路徑(/static)的請(qǐng)求則繞過flask,直接訪問虛擬機(jī)上的文件目錄,這樣也有效地減輕了flask程序的負(fù)荷。

9.獲取虛擬機(jī)的ip地址,通過瀏覽器訪問web程序。

perfect

10.別忘了把項(xiàng)目同步到git上了。

Day 2:編寫應(yīng)用配置和視圖

在編寫配置和視圖之前,首先為應(yīng)用規(guī)劃目錄結(jié)構(gòu)。

code/pkyx/├── app(應(yīng)用目錄)│ ├── config.py(配置文件)│ ├── forms.py(表單文件)│ ├── init.py│ ├── main(主體模塊)│ │ ├── errors.py(錯(cuò)誤視圖)│ │ ├── init.py│ │ └── views.py(主體視圖)│ ├── static(靜態(tài)文件目錄)│ │ └── style.css│ ├── templates(模版文件目錄)│ │ ├── 404.html│ │ ├── 500.html│ │ ├── index.html│ │ └── pk.html│ └── users(用戶模塊)│ ├── init.py│ └── views.py├── manage.py接下來我們?cè)僮鲆恍?zhǔn)備工作,用pip安裝如下幾個(gè)擴(kuò)展。

1.接下來,編寫表單文件。

首先從WTF擴(kuò)展中導(dǎo)入Form類,我們要定義的表單類會(huì)繼承到這個(gè)Form類,接下來簡(jiǎn)單地為表單定義三個(gè)域,兩個(gè)文本輸入框,validators中加入了wtforms.validators中的DataRequired的實(shí)例,它將會(huì)把這兩個(gè)文本框設(shè)置為必填項(xiàng)。最后還有一個(gè)提交域,也就是提交該表單的按鈕。

2.編寫藍(lán)本文件。

藍(lán)本(Flask-Blueprint)有許多用途,其中一個(gè)常見的用途即是為應(yīng)用的模塊做url的劃分。

在一個(gè)應(yīng)用的 URL 前綴和(或)子域上注冊(cè)一個(gè)藍(lán)圖。 URL 前綴和(或)子域的參數(shù) 成為藍(lán)圖中所有視圖的通用視圖參數(shù)(缺省情況下)。關(guān)于藍(lán)本的詳細(xì)說明:http://dormousehole.readthedocs.org/en/latest/blueprints.html#blueprints

在Blueprint的參數(shù)中還可以指定模塊的靜態(tài)文件路徑以及模版文件路徑。

3.編寫錯(cuò)誤響應(yīng)視圖。

為應(yīng)用編寫錯(cuò)誤的響應(yīng)視圖十分重要,這里簡(jiǎn)單地定義了兩個(gè)視圖,分別對(duì)應(yīng)錯(cuò)誤404和錯(cuò)誤500的響應(yīng),注意這里使用的main為上一個(gè)中定義的藍(lán)本對(duì)象,若在英語中注冊(cè)了藍(lán)本,被裝飾器包裝的視圖函數(shù)都會(huì)注冊(cè)到應(yīng)用中,它會(huì)把 構(gòu)建Blueprint時(shí)所使用的名稱(在本例為simple_page)作為函數(shù)端點(diǎn) 的前綴。

4.編寫主體視圖。

這里定義了首頁(/)和比較頁(/pk)的對(duì)應(yīng)視圖,在index中,我們把之前定義的PkForm表單實(shí)例化,作為渲染模版函數(shù)render_template的上下文參數(shù)傳入到模版中渲染。在pk視圖中,它接受來自index表單中post提交的數(shù)據(jù),因此要在它的裝飾器的methods參數(shù)中加上'POST屬性(默認(rèn)只有GET),注意要把request.form作為表單的構(gòu)造函數(shù)的參數(shù)傳入,否則表單將不能接收到任何數(shù)據(jù),然后我們用表單到validate_on_submit方法來判斷表單的數(shù)據(jù)是否合法,若正確,則把輸入框的兩個(gè)數(shù)據(jù)拿出,渲染到比較頁中,否則,便簡(jiǎn)單地返回一個(gè)顯示錯(cuò)誤的響應(yīng)。

5.編寫模版。

這里簡(jiǎn)單地在模版定義一個(gè)表單,它指向之前定義的pk視圖,當(dāng)然了,只有這么簡(jiǎn)單的顯示是遠(yuǎn)遠(yuǎn)不夠的,在static中定義css樣式文件,在頁面的頭部的link標(biāo)簽的href屬性指定用url_for()反向解析得到的靜態(tài)文件路徑(這里要感謝強(qiáng)大的jinjia2模版:))。

這里的效果大概如下:

接著編寫比較頁的模版。

6.定義配置文件。

到這里,應(yīng)用的框架基本清晰,但我們需要更加靈活的啟動(dòng)和運(yùn)行應(yīng)用,在app目錄下編寫全局的配置文件。

在BaseConfig中定義了應(yīng)用的一些基本配置,例如秘鑰,郵箱配置等等,下面所有的其它配置都會(huì)繼承BaseConfig,擴(kuò)展出的其它配置,這里定義了一個(gè)DevConfig(開發(fā)配置),顧名思義是在開發(fā)中的配置,除此之外,還可以定義其它類型的配置(如生產(chǎn)配置,測(cè)試配置等),在DevConfig中我們擴(kuò)展了關(guān)于MongoDB連接(Flask-PyMongo)的配置,以及一個(gè)靜態(tài)方法init_app,它會(huì)應(yīng)用進(jìn)行一些配置的初始化(如建立數(shù)據(jù)庫的連接)。

7.編寫創(chuàng)建應(yīng)用的函數(shù)。

這里編寫了一個(gè)創(chuàng)建和初始化應(yīng)用的函數(shù),它將負(fù)責(zé)為應(yīng)用初始化傳入的配置,使用配置的init_app初始化自身,以及注冊(cè)前面編寫的藍(lán)本。

8.建立管理應(yīng)用腳本(manage.py)。

最后應(yīng)用還需要一個(gè)全局的管理腳本,這里暫時(shí)只需要加上啟動(dòng)應(yīng)用的代碼。

9.啟動(dòng)和運(yùn)行應(yīng)用。

完成上面的步驟,應(yīng)用就能跑起來了。

Day 3:編寫RESTful API和測(cè)試數(shù)據(jù)庫

前面已經(jīng)完成了視圖,模板,表單的工作,應(yīng)用也已經(jīng)可以運(yùn)行了。

接下來開始編寫API了,REST(表現(xiàn)層狀態(tài)轉(zhuǎn)換)設(shè)計(jì)風(fēng)格是當(dāng)前最流行的設(shè)計(jì)模式,接下來將會(huì)為應(yīng)用編寫REST風(fēng)格的API。

關(guān)于RESTful

1.還是老規(guī)矩,新建API模塊的目錄,和init.py,定義Blueprint。

2.測(cè)試數(shù)據(jù)庫

在app模塊的初始化中,我們創(chuàng)建了MongoDB的連接實(shí)例,但這個(gè)實(shí)例是還沒有綁定到當(dāng)前的應(yīng)用上下文的,因此還要在create_app中為mongo實(shí)例用創(chuàng)建出來的app添加到連接實(shí)例的init_app方法,這時(shí)候,MongoDB就正式可以在應(yīng)用中工作了,只需要在其他文件中導(dǎo)入app模塊的mongo實(shí)例( from app import mongo)。

接下來,在mongo shell中新建一個(gè)存放條目的集合,插入一條數(shù)據(jù)。。

3.編寫工具函數(shù)(utils)。

這里的兩個(gè)工具函數(shù)(bson_to_json,bson_obj_id)是待會(huì)在編寫API視圖的時(shí)候要用到的,其作用分別是把MongoDB的BSON(文檔的數(shù)據(jù)格式)轉(zhuǎn)換為JSON和把id轉(zhuǎn)換為MongoDB中的ObjectId形式,因?yàn)檫@兩個(gè)功能都難以用python內(nèi)置的函數(shù)實(shí)現(xiàn),而pymongo為我們提供的bson模塊提供了很好用的json_util,使得我們很方便地去實(shí)現(xiàn)MongoDB和Python之間的數(shù)據(jù)格式轉(zhuǎn)換。

一張圖就能解釋其中的流程。

4.編寫REST API。

終于到了重中之重的步驟了,在Python的Web框架中實(shí)現(xiàn)REST API不是一件難事,Python社區(qū)也有許多關(guān)于REST的包(EVE,REST framework等),而在Flask里,flask默認(rèn)為開發(fā)者提供了可組裝視圖(Pluggable View),其中里面有一個(gè)MethodView,就是專門為開發(fā)者設(shè)計(jì)REST風(fēng)格的視圖的,這種類視圖有一個(gè)as_view()方法,使用它可以直接把類視圖轉(zhuǎn)換成平時(shí)使用的普通視圖,在有重用視圖的需求時(shí),更是比普通函數(shù)視圖更加地靈活。

首先,編寫好一個(gè)API類,繼承MethodView,簡(jiǎn)單地實(shí)現(xiàn)get、post、put、delete四個(gè)方法,分別對(duì)應(yīng)四個(gè)HTTP方法對(duì)應(yīng)的處理句柄。在代碼的最后加上路由的規(guī)則,映射到不同的方法中,注意get方法中有兩種情況,一種是提供id,只返回特定的資源,不提供id則返回所有(或前N條)資源,用add_url_route()方法動(dòng)態(tài)地添加路由。

最后先簡(jiǎn)單地實(shí)現(xiàn)一下get方法,用pymongo把資源從數(shù)據(jù)庫拉取,find()方法返回的是結(jié)果游標(biāo),注意這里用到了bson_to_json()方法,前面說過了,這是把MongoDB的文檔格式從bson轉(zhuǎn)換為json格式,拿到存放json數(shù)據(jù)的列表之后,再用json.dumps()返回之。最后客戶端得到的就是一個(gè)json格式的對(duì)象數(shù)組了。

最后的最后要注意的是在find()方法中傳入了一個(gè)params字典,這個(gè)字典是存放GET請(qǐng)求后面帶的參數(shù)的鍵值對(duì)的,有了條件查詢,我們構(gòu)建的API會(huì)更加靈活。

其他的方法就按照各自的條件實(shí)現(xiàn)。

5.測(cè)試REST API。

這里用Postman向服務(wù)器的api地址發(fā)送了一個(gè)GET請(qǐng)求,參數(shù)是之前插入到MongoDB中的文檔的id字符串,最后得到一條結(jié)果。(若不加參數(shù)的話,則得到所有結(jié)果)

再測(cè)試了另外一條GET請(qǐng)求,這次則是加上了數(shù)據(jù)的屬性與值作為query string,發(fā)送查詢請(qǐng)求,結(jié)果得到一條記錄。

Day 4:使用Supervisor和Gunicorn優(yōu)化應(yīng)用

Sueprvisor是Linux上的一個(gè)可以監(jiān)控應(yīng)用和進(jìn)程的工具,我們用它來作為守護(hù)進(jìn)程,自動(dòng)化地啟動(dòng)和停止應(yīng)用。

首先在系統(tǒng)上用sudo apt-get install supervisor安裝它。

接著再用pip install gunicorn安裝gunicorn,gunicorn是用python實(shí)現(xiàn)的高性能wsgi服務(wù)器,flask自帶的wsgi服務(wù)器不適合在生產(chǎn)環(huán)境使用,我們使用gunicorn作為flask應(yīng)用的服務(wù)器,提高應(yīng)用的吞吐量和響應(yīng)速度。

接下來在應(yīng)用的目錄下新建一個(gè)gunicorn的配置文件,里面配置了四個(gè)工作進(jìn)程(wokers)和綁定的端口(bind)。

除此之外還要?jiǎng)?chuàng)建應(yīng)用專屬的supervisor的配置文件,其中主要的參數(shù)有幾個(gè):

用supervisor啟動(dòng)應(yīng)用進(jìn)程也非常簡(jiǎn)單,只需要在supervisorctl的控制臺(tái)里輸入對(duì)應(yīng)的命令即可運(yùn)行應(yīng)用。

注意的是,在使用supervisor之前,要先要用supervisord -c [conf_path]和supervisorctl -c [conf_path]命令指定好supervisor自身的配置文件。

當(dāng)然了,在開發(fā)調(diào)試環(huán)境下還是不太適宜用gunicorn和supervisor來啟動(dòng)應(yīng)用的,因?yàn)檫@樣做不便于查看應(yīng)用的輸出和錯(cuò)誤信息,而要在日志中觀察應(yīng)用的運(yùn)行狀態(tài)。

Day 5:編寫用戶和認(rèn)證模塊

使用Flask-Login擴(kuò)展能夠很方便地為你的應(yīng)用實(shí)現(xiàn)用戶的會(huì)話和登錄功能。

首先用pip install Flask-Login安裝之。

除此之外,在認(rèn)證模塊要用到Flask-httpauth這個(gè)包,我們將在用戶的REST API用認(rèn)證的方式來管理請(qǐng)求。

安裝方式:pip install Flask-httpauth。

1.說到用戶模塊,當(dāng)然離不開登錄/注冊(cè)功能,那么我們首先編寫登錄和注冊(cè)表單。

代碼包括了最常用的幾個(gè)域,這里就沒什么好說的了。

2.編寫用戶模型(Model)。

盡管我們的應(yīng)用沒有采用ORM模型的形式,而是用pymongo來直接與MongoDB交互,但我們還是需要編寫一個(gè)通用的用戶模型,一是因?yàn)镕lask-Login中要用到關(guān)于用戶的模型對(duì)象,二是方便在認(rèn)證模塊中管理用戶。

新建一個(gè)models.py文件,定義一個(gè)User類,添加Flask-Login模塊里的UserMixin,這個(gè)Mixin會(huì)為我們定義的用戶類聲明一些通用的用戶狀態(tài)的property,如is_anonymous, is_authorized, is_active等等,混入U(xiǎn)serMixin后,User類便能作為Flask-Login的用戶模型一樣被對(duì)待。

在這個(gè)用戶類定義了四個(gè)方法。

1)gen_passwd_hash(password)

返回用哈希算法加密后的密碼,因?yàn)槲覀兊拿艽a是不能讓它明文地保存在數(shù)據(jù)庫的,在這里使用werkzeug.security中的generate_password_hash方法來加密密碼。

2)verify_passwd(passwd_hash, passwd)

把輸入的密碼與加密的哈希密碼做對(duì)比,驗(yàn)證其正確性。

3)gen_auth_token(self, expiration)

生成一個(gè)帶有過期驗(yàn)證的訪問令牌。

4)verify_auth_token(token)

驗(yàn)證訪問令牌,若成功,返回用戶信息。

3.初始化LoginManager。

在應(yīng)用模塊中新建Flask-Login的LoginManager的實(shí)例,用它當(dāng)前綁定應(yīng)用,指定用戶登錄的視圖(這里是'users.login')。你必須提供一個(gè) user_loader回調(diào)。這個(gè)回調(diào)用于從會(huì)話中存儲(chǔ)的用戶 ID 重新加載用戶對(duì)象。它應(yīng)該接受一個(gè)用戶的ID 作為參數(shù),并且返回相應(yīng)的用戶對(duì)象。

https://flask-login.readthedocs.org/en/latest/

4.編寫用戶主要視圖。

這里分別定義了register(注冊(cè)),login(登錄),profile(用戶資料),logout(注銷)四個(gè)視圖,這里要注意的是錯(cuò)誤的判斷以及用戶驗(yàn)證流程,用flask-login中相應(yīng)的login_user(user)和logout_user()來實(shí)現(xiàn)登錄/登出功能,最后記得在需要保護(hù)的視圖中添加上login_required裝飾器,防止未經(jīng)登錄的訪問。

5.添加/修改登錄注冊(cè)模版。

6.測(cè)試登錄/注冊(cè)等功能。

前面已經(jīng)實(shí)現(xiàn)了用戶的登錄功能,現(xiàn)在注冊(cè)一個(gè)用戶并登錄測(cè)試應(yīng)用。

注冊(cè)。

接著登錄。

登錄成功。

7.編寫用戶認(rèn)證模塊。

前面在定義用戶類的時(shí)候就已經(jīng)寫好了一些認(rèn)證的方法。

現(xiàn)在我們使用flask-httpauth來構(gòu)建帶有用戶認(rèn)證的REST API。

在api模塊目錄下新建users.py。

創(chuàng)建一個(gè)HTTPBasicAuth實(shí)例,定義核心的verify_password函數(shù),它將完成用戶認(rèn)證的功能,這里需要用auth的verify_password裝飾這個(gè)函數(shù)。

verify_password中提供了兩種認(rèn)證方式,首先是用token認(rèn)證,如果不通過則用用戶+密碼的方式入庫驗(yàn)證。

接著用login_requried包裝一個(gè)獲取token的視圖和一個(gè)資源視圖。

接著開始測(cè)試api。

如果不用認(rèn)證的方式去訪問資源的話,會(huì)得到一個(gè)access denied的響應(yīng)。

我們用郵箱(用戶名):密碼的方式訪問資源,成功返回一個(gè)資源。

然后用認(rèn)證的方式請(qǐng)求token所在的視圖,獲取到帶有過期時(shí)間和token的json,下面不用用戶名跟密碼,而是用token代替去訪問應(yīng)用資源,同樣正確地返回資源。

Day 6:用模版繼承組件化應(yīng)用

今天來為應(yīng)用完善之前寫好的模板。

在完善頁面前最好先為模板添加上一些樣式,不然頁面看起來不美觀,也沒有層次感,不便于調(diào)整頁面元素。因此在原來的基礎(chǔ)上,可以添加上自己寫的樣式,用link的方式導(dǎo)出到前端,或者直接使用開源的css框架,在這里使用的是semantic-ui,用bower安裝到應(yīng)用的資源目錄,然后就可以編寫模板了。

由于一個(gè)網(wǎng)站中通常會(huì)有一些重復(fù)的基礎(chǔ)組件(如導(dǎo)航欄,頂部,通用樣式等),這樣一來在每個(gè)頁面文件中我們都要把這些幾乎相同的代碼拷貝,而且當(dāng)要改動(dòng)元素時(shí)得每個(gè)文件都要進(jìn)行修改,給開發(fā)帶來許多的不便,這時(shí)候便要用到j(luò)injia2的模板繼承功能,使用模板,我們能把這些通用的部分封裝出來作為模板,需要替換的地方只需要在特定的位置添加一個(gè)塊,在繼承的子模板中填充塊的內(nèi)容即可。

1.下面在模板目錄下新建一個(gè)基礎(chǔ)文件(base.html)作為需要繼承的通用模板。

在該目標(biāo)中包含了一些基本樣式和腳本,定義了三個(gè)需要填充的塊,分別是head頭部,主體內(nèi)容和js文件。

2.繼承父模板。

修改之前定義的首頁文件(index.html),用extends的方式繼承了父模板,然后只需要在相應(yīng)的塊中補(bǔ)充內(nèi)容,子模板在渲染的時(shí)候便會(huì)把塊中的內(nèi)容導(dǎo)出到自身的對(duì)應(yīng)塊中,構(gòu)造和實(shí)現(xiàn)頁面,這里還把頂部欄(header.html)以及登錄框(login.html)分別獨(dú)立出一個(gè)組件,只供特定的模板使用,這樣的導(dǎo)入方式會(huì)帶來更大的靈活性。

3.編寫組件。

可以把這里的組件理解為頁面中的一部分,因此在寫代碼的時(shí)候只需吧對(duì)應(yīng)部分的html元素完成即可。

頂部欄組件

登錄框(模態(tài)框)組件

4.整合模板。

現(xiàn)在處理過后的組件可以像積木一樣裝載在應(yīng)用上了,這里簡(jiǎn)單地應(yīng)用在幾個(gè)頁面,查看效果。

Day 7:編寫主功能

接著上次的地方開始做。

1.建立創(chuàng)建條目的頁面,一個(gè)表單搞定,server端向數(shù)據(jù)庫插入一條文檔,so easy。

2.創(chuàng)建條目之后,系統(tǒng)會(huì)重定向到條目的信息頁面,編寫信息頁面的布局。

如下所示,條目內(nèi)容將會(huì)由一個(gè)表格來展示,剛創(chuàng)建的條目只有類型一個(gè)屬性,頁面底下會(huì)有一個(gè)添加屬性的按鈕,動(dòng)態(tài)地向該條目插入屬性。

由于表格的內(nèi)容是由python端進(jìn)行渲染的,而一個(gè)條目的屬性可能有多種類型。如下圖所示:

這就帶來一個(gè)問題,因?yàn)閷傩灶愋筒灰欢ㄊ羌兾谋?,因此不能?jiǎn)單地從數(shù)據(jù)庫取數(shù)據(jù)然后再直接渲染。

這里要實(shí)現(xiàn)動(dòng)態(tài)的渲染,要在ajax和server端之間定義一套規(guī)則,向條目添加屬性的時(shí)候會(huì)按照不同的類型來構(gòu)造出特定的數(shù)據(jù)格式,然后python端在知道格式的情況下,用自定義的渲染器實(shí)現(xiàn)html的插入。

有了這個(gè)思路,馬上開始編寫代碼。

當(dāng)點(diǎn)擊添加屬性按鈕后,底下會(huì)折疊處一個(gè)標(biāo)簽頁菜單,選擇不同的類型時(shí),下面的輸入框也會(huì)相應(yīng)地變化。

當(dāng)然,js也要相應(yīng)地配合,用ajax請(qǐng)求服務(wù)器端,進(jìn)行數(shù)據(jù)更新。

根據(jù)選擇類型獲取屬性值。

Ajax請(qǐng)求

3.編寫渲染器。

jinjia2的靈活性使得我們可以方便地在模板中使用python代碼,下面定義了一個(gè)簡(jiǎn)單的類型渲染器,根據(jù)傳入的【屬性名,屬性值,屬性類型】構(gòu)造出html。

然后在頁面中這樣調(diào)用,記得使用safe過濾器取消轉(zhuǎn)義。

4.增加編輯/刪除屬性方法。

添加屬性有了,怎么可以沒有編輯和刪除屬性的方法呢?

一開始想用可編輯表格的方式對(duì)表格的數(shù)據(jù)進(jìn)行即時(shí)修改,卻發(fā)現(xiàn)這樣做會(huì)帶來一些問題,最終放棄之。

改成了雙擊表格列,用模態(tài)框修改之。

修改成功之后會(huì)刷新頁面,看到修改后的表格。

5.完善表單驗(yàn)證。

因?yàn)橹白龅谋韱悟?yàn)證實(shí)在是太簡(jiǎn)陋了,出于安全考慮,一定要對(duì)表單驗(yàn)證(尤其是用戶信息方面)加以完善。

編輯表單文件,在之前的基礎(chǔ)上,我們改用一個(gè)validators字典來存放不同表單域的規(guī)則,在用戶名和密碼中都加上了長度以及正則表表達(dá)式加以限制。

在頁面中也要提示用戶怎么填寫表單。

6.完善樣式。

最后再修飾一下頁面。

Day 8:使用GridFS實(shí)現(xiàn)文件上傳

文件上傳有許多種方法,一般用文件系統(tǒng)的io即可,這里使用了mongodb的GridFS系統(tǒng),mongodb推薦使用它來保存大型文件,

這里先嘗鮮試用一下,用gridfs實(shí)現(xiàn)用戶頭像的上傳。

在flask端,用request.files來接收上傳的頭像圖片,判斷圖片的擴(kuò)展名是否符合格式,如果合法,用werkzurg.utils的secure_filename方法來替換和過濾文件名的特殊字符,接下來實(shí)例化GridFS類,它接受一個(gè)database和集合作為參數(shù),用fs對(duì)象的put方法上傳到GridFS,返回的Object Id指向的是db.avatar.files插入的文檔,把頭像id以及用戶的資料信息一并保存到數(shù)據(jù)庫。

在前端的頁面用url_for()方法反向解析出圖片的地址,首先要編寫好獲取頭像的路由,它接受頭像的Object Id作為參數(shù),從fs系統(tǒng)中取出頭像圖片的數(shù)據(jù),圖片的二進(jìn)制數(shù)據(jù)會(huì)保存在db.avatar.chunks中,這里獲取圖片之后,構(gòu)造一個(gè)content-type為圖片格式的response,否則當(dāng)打開url時(shí),圖片數(shù)據(jù)不能正確被瀏覽器解析,在img的src屬性中填上路由即可顯示圖片。

用戶的資料可能有不全的情況,用jinja2的Environment Filter來編寫自定義的過濾器,使數(shù)據(jù)的顯示更加人性化。

最后編寫比較頁面,這里要注意屬性的順序排置,實(shí)現(xiàn)正確地渲染。

到此網(wǎng)站頁面端初步完成。

Day 9:配置Celery&Redis運(yùn)行后臺(tái)任務(wù)

有些時(shí)候,我們的應(yīng)用會(huì)執(zhí)行一些后臺(tái)任務(wù),例如一些不會(huì)與用戶直接交互,實(shí)時(shí)性要求較低的動(dòng)作。例如用戶注冊(cè)的時(shí)候,通常會(huì)發(fā)送一封帶有認(rèn)證token鏈接的郵件到用戶的郵箱,因?yàn)榘l(fā)送郵件這個(gè)動(dòng)作會(huì)比較耗時(shí),如果同一時(shí)間有大量注冊(cè)的請(qǐng)求,就可能會(huì)出現(xiàn)阻塞,影響用戶瀏覽的體驗(yàn),這時(shí)候我們更希望把任務(wù)放到后臺(tái)進(jìn)行,那么Celery會(huì)是一個(gè)合適的選擇,Celery是一個(gè)分布式的任務(wù)隊(duì)列,負(fù)責(zé)任務(wù)的執(zhí)行與調(diào)度。

Celery的架構(gòu)由三部分組成,消息中間件(message broker),任務(wù)執(zhí)行單元(worker)和任務(wù)執(zhí)行結(jié)果存儲(chǔ)(task result store)組成。

這里用Redis作為Celery的Broker,負(fù)責(zé)傳遞通訊消息。

用pip install flask-celery-helper安裝Celery和它的Flask擴(kuò)展,用pip install redis安裝Redis的python擴(kuò)展。

安裝好之后要在配置文件中添加上celery和redis的相關(guān)配置。

首先重構(gòu)目錄的結(jié)構(gòu),把擴(kuò)展移到extensions文件下,在init中用工廠函數(shù)初始化應(yīng)用。

1.在app目錄下新建一個(gè)tasks目錄,里面放的就是Celery要處理的任務(wù)文件。

這里新建一個(gè)異步發(fā)送郵件的任務(wù),用@celery.task裝飾之。

2.在視圖函數(shù)中封裝一個(gè)發(fā)送郵件的函數(shù),以及編寫用戶認(rèn)證的視圖。

認(rèn)證的方式用帶有時(shí)間戳的token。

3.運(yùn)行Celery。

加上-A參數(shù)后Celery會(huì)去識(shí)別用戶自定義的配置文件,后面接一個(gè)celery實(shí)例所在的模塊文件。

運(yùn)行之后,去注冊(cè)一個(gè)賬號(hào)。

點(diǎn)擊郵件中的激活連接,驗(yàn)證token:

Day 10:編寫Dockerfile

最后一步:編寫部署環(huán)境的腳本

首先把項(xiàng)目用到的配置文件都放在項(xiàng)目的conf目錄下,如下圖顯示了項(xiàng)目的supervisor的配置文件。

接著編寫Dockerfile文件,方便快速地用docker部署好項(xiàng)目的容器環(huán)境。

最后就可以在生產(chǎn)的服務(wù)器上測(cè)試運(yùn)行項(xiàng)目了。

74
73
25
news

版權(quán)所有? 億企邦 1997-2022 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉