AI畫家第三彈——畢業(yè)設(shè)計大殺器之Flask

image

上一篇介紹了圖像風(fēng)格遷移的一個最基本實現(xiàn)代芜,雖然在控制臺實現(xiàn)了功能岸浑,但是想要實際使用侣夷,應(yīng)用到一個app或者網(wǎng)頁上光靠上一節(jié)的內(nèi)容肯定是不行的最仑。那怎么樣才可以將風(fēng)格遷移這個功能變成一個可以實際使用的小程序呢?不著急赏壹,在實現(xiàn)上述功能前鱼炒,我們先來介紹一個小東西,也就是這篇文章的主角蝌借,我把他稱為"畢業(yè)設(shè)計大殺器“的Flask框架昔瞧。

前后端分離

在介紹Flask之前,我們先介紹下什么是前后端分離菩佑。因為如果不介紹前后端分離就不會理解為啥要選擇Flask了自晰。前后端分離是目前互聯(lián)網(wǎng)項目開發(fā)的標(biāo)準(zhǔn)使用方式,其核心思想簡單理解為是前端頁面(或者app等多端)通過ajax(或者其他請求方式)調(diào)用后端的restuful api接口并使用json數(shù)據(jù)進行交互稍坯。其目的是為了將項目解耦合酬荞,達到"術(shù)業(yè)有專攻”的效果。因為在以往的web項目中瞧哟,后端人員的工作量非常大混巧,用過jsp的人都知道,那真的是又當(dāng)?shù)之?dāng)媽勤揩,既要會寫后臺邏輯還要會弄樣式咧党。但是采用了前后端分離的架構(gòu)之后,前后端人員就可以各司其職了陨亡。

前端人的追求

前端追求的是:頁面表現(xiàn)傍衡,速度流暢深员,兼容性,用戶體驗等等蛙埂。

把精力放在html5辨液,css3,jquery箱残,angularjs,bootstrap止吁,reactjs被辑,vuejs,webpack敬惦,less/sass盼理,gulp,nodejs俄删,Google V8引擎宏怔,javascript多線程,模塊化畴椰,設(shè)計模式臊诊,瀏覽器兼容性,性能優(yōu)化等等斜脂。

后端人的追求

后端追求的是:三高(高并發(fā)抓艳,高可用,高性能)帚戳,安全玷或,存儲,業(yè)務(wù)等等片任。

把精力放在語言基礎(chǔ)偏友,設(shè)計模式,底層原理对供,linux位他,mysql事務(wù)隔離與鎖機制,mongodb犁钟,http/tcp棱诱,多線程,分布式架構(gòu)涝动,彈性計算架構(gòu)迈勋,微服務(wù)架構(gòu),性能優(yōu)化醋粟,以及相關(guān)的項目管理等等靡菇。

應(yīng)用服務(wù)器重归、Web服務(wù)器、Restful

應(yīng)用服務(wù)器:一般指像tomcat厦凤,jetty這類的服務(wù)器可以解析動態(tài)資源也可以解析靜態(tài)資源鼻吮,但解析靜態(tài)資源的能力沒有web服務(wù)器好。

Web服務(wù)器:一般指像nginx较鼓,apache這類的服務(wù)器椎木,他們一般只能解析靜態(tài)資源。

靜態(tài)資源就是類似于html博烂、js香椎、圖片這些多次訪問也不會變化的資源

一般都是只有web服務(wù)器才能被外網(wǎng)訪問,應(yīng)用服務(wù)器只能內(nèi)網(wǎng)訪問禽篱。

RESTful

REST的全稱是representational state transfer畜伐,即表征狀態(tài)轉(zhuǎn)移。在理解這個名詞之前我們先來看幾個名詞(感覺需要知道的前置知識好多疤陕省)玛界。

資源(resources)

所謂的資源就是網(wǎng)絡(luò)上的一個實體,它可以使一個圖片悼吱,一個文本慎框,一個服務(wù),你可以用一個URI指向它舆绎,每種資源對應(yīng)一個特定的URI鲤脏,要獲取這個資源訪問它的URI就行了,所謂的上網(wǎng)吕朵,其實就是與網(wǎng)絡(luò)上的資源進行一系列的互動就是了猎醇。

表征(representation)

怎么把資源表現(xiàn)出來就是表征的意義,比如一段文本是txt努溃、html還是json硫嘶,圖片是jpg還是png,以http協(xié)議為例梧税,就是Accept和content-type中的內(nèi)容沦疾,說明了資源的類型。

狀態(tài)轉(zhuǎn)移(state tranfer)

訪問一個網(wǎng)站第队,就是客戶端和服務(wù)端的一個交互過程哮塞,客戶端想要操作服務(wù)端,就必須通過某種手段讓服務(wù)端的狀態(tài)發(fā)生變化凳谦,具體到http協(xié)議中就是http的幾種方法:GET用來獲取資源忆畅,POST用來新建資源,PUT用來更新資源尸执,DELETE用來刪除資源家凯。

理解RESTful

  1. 使用URI來表示每一個資源
  2. 為每一個資源確定它的表現(xiàn)形式
  3. 使用4個方法來操作這些資源

什么是Flask缓醋?

介紹完前后端分離后,我們就開始介紹下Flask是什么吧绊诲。

Flask是一個使用 Python 編寫的輕量級 Web 應(yīng)用框架送粱。其 WSGI 工具箱采用 Werkzeug ,模板引擎則使用 Jinja2掂之。Flask也被稱為 “microframework” 抗俄,即"微框架",因為它使用簡單的核心世舰,用 extension 增加其他功能橄镜。Flask沒有默認使用的數(shù)據(jù)庫、窗體驗證工具冯乘。

理解下"微"

"微"框架中的“微”(micro) 并不表示你需要把整個 Web 應(yīng)用塞進單個 Python 文件(雖然確實可以 ),也不意味著 Flask 在功能上有所欠缺晒夹。微框架中的“微”意味著 Flask 旨在保持核心簡單而易于擴展裆馒。Flask 不會替你做出太多決策——比如使用何種數(shù)據(jù)庫。而那些 Flask 所選擇的——比如使用何種模板引擎——則很容易替換丐怯。除此之外的一切都由可由你掌握喷好。默認情況下,F(xiàn)lask 不包含數(shù)據(jù)庫抽象層读跷、表單驗證梗搅,或是其它任何已有多種庫可以勝任的功能。然而效览,F(xiàn)lask 支持用擴展來給應(yīng)用添加這些功能无切,如同是 Flask 本身實現(xiàn)的一樣。眾多的擴展提供了數(shù)據(jù)庫集成丐枉、表單驗證哆键、上傳處理、各種各樣的開放認證技術(shù)等功能瘦锹。Flask 也許是“微小”的籍嘹,但它已準(zhǔn)備好在需求繁雜的生產(chǎn)環(huán)境中投入使用。

什么是wsgi弯院?

全名Web Server Gateway Interface辱士,即服務(wù)器網(wǎng)關(guān)接口,是應(yīng)用程序和Web服務(wù)器之間的一種接口听绳∷痰猓可以理解為是服務(wù)器程序和應(yīng)用程序的一個約定,規(guī)定了各自使用的接口和功能辫红,以便二和互相配合凭涂。

這里因為篇幅原因就不給出詳細解釋了祝辣,推薦兩片文章,講的挺詳細的切油。

  1. http://www.reibang.com/p/29f66eb4e55a
  2. https://www.liaoxuefeng.com/wiki/897692888725344/923057027806560

為什么選Flask蝙斜?

我把Flask稱為畢業(yè)設(shè)計大殺器自然是有他的道理的,接下來我們看看他的幾大優(yōu)點:

  1. 插件多澎胡。查找資料方便
  2. 沒有太多繁瑣的配置步驟
  3. 各種中文資料孕荠、網(wǎng)友的受虐后的心得文章,查詢方便
  4. 部署也非常方便
  5. 社區(qū)非彻ニ活躍

實例

上面說了那么多稚伍,你們肯定還是不會理解為啥要使用Flask,別急戚宦,我們用例子說話个曙。

安裝

這里就不多說了,直接pip install flask即可受楼。(官方文檔是推薦創(chuàng)建一個虛擬環(huán)境的垦搬,這里為了方便起見,省略了這一步)艳汽。

最小的應(yīng)用

一個最小的 Flask 應(yīng)用看起來會是這樣:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

把它保存為 hello.py (或是類似的)猴贰,然后啟動terminal(powershell)來運行這個文件。 確保你的應(yīng)用文件名不是 flask.py 河狐,因為這將與 Flask對象本身沖突米绕。

python hello.py

現(xiàn)在訪問 http://127.0.0.1:5000/ ,你會看見 Hello World 早已等候多時馋艺。

image

一旦部署到遠程服務(wù)器上之后栅干,這就是一個可以用GET請求訪問的接口了,是不是很方便呢捐祠?如果想更改請求方法也很簡單非驮,只需要在@app.route()裝飾器第二個參數(shù)填入想要支持的請求方法就可以了,如下:

@app.route('/login', methods=['GET', 'POST'])

這樣雏赦,login這個路由就可以支持get和post兩種請求方式了劫笙。

路由

所謂 路由,即URL 綁定
Flask 使用 route()裝飾器把一個函數(shù)綁于一個URL上星岗, 如下:

這里是一些基本的例子:

@app.route('/hello')
def hello_world():
    return 'Hello World!'

我們便可以在本地通過localhost:xxxx/hello填大,來獲取到hello函數(shù)中的內(nèi)容。

同時俏橘,我們還可以使用add_url_rule()方法來實現(xiàn)路由的注冊

from flask import Flask

app = Flask(__name__)   
 
def hello():
    return 'Hello ,world!'

app.add_url_rule('/hello', viewfunc=hello)
app.run()

其實add_url_rule@app.route()裝飾器內(nèi)部封裝的一個方法允华,兩者的本質(zhì)是相同的。不信咱們看源碼:

Carbonize 2019-05-09 at 3.10.23 PM

藍圖(blueprint)

雖然說flask想實現(xiàn)一個路由非常簡單,但是在實際的項目中我們肯定是不能把所有的路由都放在初始文件中啊靴寂,文件變大不說磷蜀,還不方便管理,完全不符合模塊化開發(fā)的思想百炬。不過不用擔(dān)心褐隆,flask早就幫我們想好了應(yīng)對的辦法了。這就是藍圖剖踊。

為了在一個或多個應(yīng)用中庶弃,使應(yīng)用模塊化并且支持常用方案,F(xiàn)lask 引入了藍圖概念德澈。藍圖可以極大地簡化大型應(yīng)用并為擴展提供集中的注冊入口歇攻。

接下來則是藍圖的使用(一般位于API級的__init__.py文件中):

from flask import Flask

def create_app():
    app = Flask(__name__)

    register_blueprint(app)   # 完成藍圖注冊
    init_db(app)
    return app

def register_blueprint(app):  # 注冊藍圖
    from app.api.v1 import v1
    from app.api.v1.img import img

    app.register_blueprint(v1, url_prefix='/api/v1')  
    # url_prefix添加了這個參數(shù)后,所有藍圖路由前面機會自動添加這個參數(shù)
    # PS:這個參數(shù)必須是一個字符串,而且要以' / '開頭
    app.register_blueprint(img, url_prefix='/api/v1/img')

之后我們就可以在另一個文件(需要使用app對象的文件梆造,也就是存放路由函數(shù)的文件)中將它初始化

from flask import Blueprint  # 藍圖引入
 
img = Blueprint('img', __name__)  # 藍圖初始化

其實我們可以理解為就是把主頁面的app對象傳遞到了不同的路由文件中了缴守,方便了模塊化的開發(fā)。

這里如果沒有實例展示的話可能不是很容易理解镇辉,下一篇文章我們將會延續(xù)上一篇斧散,講一下如何利用Flask將圖像風(fēng)格遷移的功能變成一個可用的restful api,實例我已經(jīng)上傳了摊聋,大家可以先在微信公眾號「01二進制」后臺回復(fù)「風(fēng)格遷移API」把代碼下載下來,體驗下flask項目如何分層才不會導(dǎo)致混亂栈暇。

flask與數(shù)據(jù)庫

作為一個后臺框架麻裁,不可缺少的就是如何與數(shù)據(jù)庫打交道,flask_sqlalchemy很好的幫我們解決了這個問題源祈。

在了解flask_sqlalchemy是什么之前先看下sqlalchemy是什么煎源,我這里直接引用下廖雪峰大神的介紹:

image

直接我們也提過,flask是一個微框架香缺,通過插件來增加功能的手销,flask_sqlalchemy就是sqlalchemy的一個flask框架,目的就是為了更加方便的使用ORM技術(shù)操作數(shù)據(jù)庫图张。

接下來簡單介紹下他的使用方法锋拖。

先安裝:pip install flask_sqlalchemy

然后在初始文件中添加如下代碼以配置數(shù)據(jù)庫連接:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy() # 實例化

然后在啟動文件中添加如下代碼將flask_sqlalchemy配置到flask對象中:

def init_db(app):
    # 注冊db
    db.init_app(app)
    # 將代碼映射到數(shù)據(jù)庫中
    with app.app_context():
        db.create_all(app=app)

這時候別忘了兩件事:數(shù)據(jù)庫的連接配置信息和數(shù)據(jù)表的定義

  • 數(shù)據(jù)庫的連接配置信息

我們在項目中新建一個secure.py文件(專門用于記錄敏感信息),并在其中添加如下字段

DIALECT = 'mysql'  # 要用的什么數(shù)據(jù)庫
DRIVER = 'pymysql'  # 連接數(shù)據(jù)庫驅(qū)動
USERNAME = 'xxx'  # 用戶名
PASSWORD = 'xxx'  # 密碼
HOST = 'localhost'  # 服務(wù)器
PORT = '3306'  # 端口
DATABASE = 'xxx'  # 數(shù)據(jù)庫名

SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT, DRIVER, USERNAME, PASSWORD, HOST, PORT,
                                                                       DATABASE)
SQLALCHEMY_TRACK_MODIFICATIONS = False

創(chuàng)建flask對象的時候別忘了添加下這個配置文件:

app = Flask(__name__)
app.config.from_object('app.secure')

  • 數(shù)據(jù)表的定義

以反饋(feedback)為例祸轮,如下代碼就構(gòu)建了一個非常簡單的數(shù)據(jù)庫模型了

from sqlalchemy import Column, Integer, String

from app.model import db
from app.utils import common_utils

class FeedBack(db.Model):
    # 反饋記錄的id
    id = Column(Integer, primary_key=True, autoincrement=True)
    # 反饋人的uid
    uid = Column(String(50), nullable=False)
    # 反饋的內(nèi)容
    content = Column(String(50), nullable=False)
    # 反饋人的聯(lián)系方式
    contact = Column(String(50), nullable=False)
    # 反饋的來源
    origin = Column(Integer, nullable=False)
    # 反饋的時間
    created_time = Column(String(50), nullable=False)

    def __init__(self, uid, content, contact, origin):
        self.uid = uid
        self.content = content
        self.contact = contact
        self.origin = origin
        self.created_time = common_utils.get_date_now()

然后打開數(shù)據(jù)庫服務(wù)兽埃,啟動flask項目,沒有報錯就說明成功了适袜。

最后

我們總結(jié)下柄错,這篇文章的主角是flask,但是想要理解為啥要使用flask的話我們必須要有前后端分離的概念,不然我們是不會體會到flask的便捷之處的售貌。然后緊接著介紹了我認為剛開始使用flask時的幾個比較重要的東西:路由给猾、藍圖和ORM插件。因為篇幅原因颂跨,沒有非常詳細的介紹使用方法敢伸,但是事實上只要會了這三個應(yīng)付畢業(yè)設(shè)計是綽綽有余的,這也就是我將其稱為畢業(yè)設(shè)計大殺器的原因毫捣。那么在哪可以學(xué)到flask呢详拙?

image

在微信公眾號「01二進制」后臺回復(fù)「flask視頻」即可獲得一份非常非常優(yōu)質(zhì)的flask視頻

下一篇將會介紹如何用flask結(jié)合風(fēng)格遷移模型給你的應(yīng)用程序提供一個可用的RESTful API,喜歡的小伙伴可以關(guān)注轉(zhuǎn)發(fā)和支持蔓同,謝謝??

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饶辙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子斑粱,更是在濱河造成了極大的恐慌弃揽,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件则北,死亡現(xiàn)場離奇詭異矿微,居然都是意外死亡,警方通過查閱死者的電腦和手機尚揣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門涌矢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人快骗,你說我怎么就攤上這事娜庇。” “怎么了方篮?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵名秀,是天一觀的道長。 經(jīng)常有香客問我藕溅,道長匕得,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任巾表,我火速辦了婚禮汁掠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘集币。我一直安慰自己调塌,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布惠猿。 她就那樣靜靜地躺著羔砾,像睡著了一般负间。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上姜凄,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天政溃,我揣著相機與錄音,去河邊找鬼态秧。 笑死董虱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的申鱼。 我是一名探鬼主播愤诱,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辑畦,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎科吭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猴鲫,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡对人,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了拂共。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牺弄。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖宜狐,靈堂內(nèi)的尸體忽然破棺而出势告,到底是詐尸還是另有隱情,我是刑警寧澤肌厨,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站豁陆,受9級特大地震影響柑爸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盒音,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一表鳍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧祥诽,春花似錦譬圣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春绳姨,著一層夾襖步出監(jiān)牢的瞬間登澜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工飘庄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留脑蠕,地道東北人。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓跪削,卻偏偏與公主長得像谴仙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子碾盐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容