Flask框架是Python開(kāi)發(fā)的一個(gè)基于Werkzeug和Jinja 2的web開(kāi)發(fā)微框架,它的優(yōu)勢(shì)就是極其簡(jiǎn)潔, 但又非常靈活,而且容易學(xué)習(xí)和應(yīng)用。因此Flask框架是Python新手快速開(kāi)始web開(kāi)發(fā)最好的選擇,此外, 使用Flask框架的另一個(gè)好處在于你可以非常輕松地將基于Python的機(jī)器學(xué)習(xí)算法或數(shù)據(jù)分析算法集成到 web應(yīng)用中。
1、可以用Flask框架做什么
從博客應(yīng)用到克隆一個(gè)facebook或者twitter,理論上你可以用Flask做任何事情。有很多庫(kù) 可以直接使用,例如flask-sockets,flask-google-maps等,而且Flask框架支持MySQL、Postgresql、 MongoDB等諸多數(shù)據(jù)庫(kù)。
我能想到的一些可以用Flask框架實(shí)現(xiàn)的web應(yīng)用類型:博客應(yīng)用、聊天應(yīng)用、儀表盤(pán)應(yīng)用、REST API、管理頁(yè)面、郵件服務(wù)等。
如果希望深入學(xué)習(xí)Flask Web開(kāi)發(fā),推薦這個(gè)教程:深入淺出Flask 安裝Flask
使用pip安裝Flask:
$ pip install flask
2、Hello,World
創(chuàng)建一個(gè)文件app.py,然后只需要幾個(gè)簡(jiǎn)單的步驟,就可以寫(xiě)出Flask版本的Hello World
引入Flask類
from flask import Flask
創(chuàng)建Flask對(duì)象,我們將使用該對(duì)象進(jìn)行應(yīng)用的配置和運(yùn)行:
app = Flask(__name__)
name 是Python中的特殊變量,如果文件作為主程序執(zhí)行,那么 __name__ 變量的值就是 __main__ ,如果是被其他模塊引入,那么 __name__ 的值就是模塊名稱。
編寫(xiě)主程序
在主程序中,執(zhí)行 run() 來(lái)啟動(dòng)應(yīng)用:
if __name__ =="__main__": app.run(debug=True, port=8080)
改名啟動(dòng)一個(gè)本地服務(wù)器,默認(rèn)情況下其地址是 localhost:5000 ,在上面的代碼中,我們使用關(guān)鍵字 參數(shù) port 將監(jiān)聽(tīng)端口修改為8080。
路由
使用app變量的 route() 裝飾器來(lái)告訴Flask框架URL如何觸發(fā)我們的視圖函數(shù):
@app.route('/')def hello_world(): return 'Hello, World!' 上面的標(biāo)識(shí),對(duì)路徑'/‘的請(qǐng)求,將轉(zhuǎn)為對(duì) hello_world() 函數(shù)的調(diào)用。很直白,對(duì)吧?
運(yùn)行
現(xiàn)在,讓我們完整地看一下app.py的整個(gè)代碼:
from flask import Flaskapp = Flask(__name__)@app.route('/')def hello_world(): return 'Hello, World!'if __name__ =="__main__": app.run(debug=True,port=8080)然后運(yùn)行起來(lái):
$ python app.py
你應(yīng)該會(huì)看到如下輸入:
現(xiàn)在就可以打開(kāi)瀏覽器訪問(wèn) http://127.0.0.1:8080/ 了:
* Serving Flask app "app" (lazy loading)
* Environment: production
* Debug mode: on
* Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 770-937-705
3、使用HTML模板
首先我們看看如何原始的HTML代碼插入Flask應(yīng)用:
from flask import Flaskapp = Flask(__name__)@app.route('/greet')def greet(): user = {'username': 'John', 'age': "20"} return '''<html> <head> <title>Templating</title> </head> <body> <h1>Hello, ''' + user['username'] + '''!, you're ''' + user['age'] + ''' years old.</h1> </body></html>'''if __name__ == '__main__':app.run(debug = True,port=8080) 在上面的代碼中,我們使用拼接的HTML字符串來(lái)展示user字典的數(shù)據(jù)。現(xiàn)在訪問(wèn) http://127.0.0.1:8080/greet:
拼接HTML字符串非常容易出錯(cuò),因此Flask使用Jinja 2模板引擎來(lái)分離數(shù)據(jù)邏輯和展示層。
我們將模板文件按如下路徑放置:
Apps folder/app.pytemplates |-/index.html
使用模板時(shí),視圖函數(shù)應(yīng)當(dāng)返回 render_template() 的調(diào)用結(jié)果。例如下面的代碼片段 渲染模板 index.html ,并將渲染結(jié)果作為視圖函數(shù)的返回值:
from flask import Flask, render_templateapp = Flask(__name__)@app.route('/hello')def hello(): return render_template('index.html', name="Alex")if __name__ == '__main__': app.run(debug = True) 在上面的代碼中,模板文件 index.html 依賴于變量 name ,其內(nèi)容如下:
<html><body> {% if name %} <h2>Hello {{ name }}.</h2> {% else %} <h2>Hello.</h2> {% endif %} </body></html>模板文件的語(yǔ)法擴(kuò)充了HTML,因此可以使用變量和邏輯。
在瀏覽器中訪問(wèn) http://127.0.0.1:8080/hello/alex :
4、使用表單
每個(gè)web應(yīng)用都需要使用表單來(lái)采集用戶數(shù)據(jù)。現(xiàn)在讓我們使用Flask框架創(chuàng)建一個(gè) 簡(jiǎn)單的表單來(lái)收集用戶的基本信息,例如名稱、年齡、郵件、興趣愛(ài)好等,我們將 這個(gè)模板文件命名為 bio_form.html
<!DOCTYPE html><html><head> <title></title></head><body> <h1>Bio Data Form</h1> <form action="showbio"> <label>Username</label> <input type="name" name="username"><br> <label>Email</label> <input type="email" name="email"><br> <label>Hobbies</label> <input type="name" name="hobbies"><br> <input type="submit" name=""> </form></body></html>
視圖函數(shù) bio_data_form 同時(shí)支持POST和GET請(qǐng)求。GET請(qǐng)求將渲染 bio_form.html 模板,而POST請(qǐng)求將重定向到 showbio :
@app.route('/form', methods=['POST', 'GET'])def bio_data_form(): if request.method == "POST": username = request.form['username'] age = request.form['age'] email = request.form['email'] hobbies = request.form['hobbies'] return redirect(url_for('showbio', username=username, age=age, email=email, hobbies=hobbies)) return render_template("bio_form.html")下面是showbio的實(shí)現(xiàn):
@app.route('/showbio', methods=['GET'])def showbio(): username = request.args.get('username') age = request.args.get('age') email = request.args.get('email') hobbies = request.args.get('hobbies') return render_template("show_bio.html", username=username, age=age, email=email, hobbies=hobbies)以及show_bio.html的內(nèi)容:
<!DOCTYPE html><html><head> <title>Bio-Data Details</title></head><body> <h1>Bio-Data Details</h1> <hr> <h1>Username: {{ username }}</h1> <h1>Email: {{ email }}</h1> <h1>Hobbies: {{ hobbies }}</h1></body></html>5、數(shù)據(jù)庫(kù)集成:使用SQLAlchemy
Flask不能直接連接數(shù)據(jù)庫(kù),需要借助于ORM(Object Relational Mapper)。 在這一部分,我們將借助于SQLAlchemy使用Postgres數(shù)據(jù)庫(kù)。
安裝Flask-SQLAlchemy和Postgres
首先安裝flask-sqlalchemy:
$ pip install flask-sqlalchemy
然后從官方下載并安裝postgres:https://postgresapp.com/
創(chuàng)建數(shù)據(jù)庫(kù)
在終端中使用下面的命令創(chuàng)建一個(gè)appdb數(shù)據(jù)庫(kù):
$ createdb appdb
更新應(yīng)用配置
修改app.config,添加數(shù)據(jù)庫(kù)相關(guān)的配置信息:
app.config['DEBUG'] = Trueapp.config['SQLALCHEMY_DATABASE_URI']='postgresql://localhost/appdb'SQLALCHEMY_TRACK_MODIFICATIONS = Truedb = SQLAlchemy(app)
然后在代碼中就可以使用這些配置數(shù)據(jù)了:
from flask import Flask, request, render_templatefrom flask_sqlalchemy import SQLAlchemy# Settingsapp = Flask(__name__)app.config['DEBUG'] = Trueapp.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/appdb'db = SQLAlchemy(app)@app.route('/')def hello_world(): return 'Hello, World!'if __name__ == '__main__': app.run()現(xiàn)在,讓我們創(chuàng)建第一個(gè)模型(Model)。所有模型的基類是db.Model,使用Column來(lái)定義 數(shù)據(jù)列:
class Post(db.Model): id = db.Column(db.Integer(), primary_key=True) post_text = db.Column(db.String(255)) def __init__(self, title, post_text): self.title = title self.post_text = post_text
在代碼中使用模型:
from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/testdb'db = SQLAlchemy(app)class Post(db.Model): id = db.Column(db.Integer(), primary_key=True) post_text = db.Column(db.String(255)) def __init__(self, title, post_text): self.title = title self.post_text = post_text@app.route('/')def index(): return "Hello World"app = Flask(__name__)if __name__ == "__main__": app.run()6、模型-數(shù)據(jù)同步
使用ORM時(shí),需要執(zhí)行遷移操作以便在模型和持久化數(shù)據(jù)之間保持同步。我們使用 Flask-Migrate這個(gè)擴(kuò)展來(lái)完成該任務(wù)。
首先安裝:
$ pip install flask-migrate$ pip install flask_script
然后在代碼中引入:
from flask_script import Managerfrom flask_migrate import Migrate, MigrateCommand
進(jìn)行必要的配置:
migrate = Migrate(app, db)manager = Manager(app)manager.add_command('db', MigrateCommand)運(yùn)行管理器:
if __name__ == '__main__': manager.run()
完整的代碼如下:
from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyfrom flask_script import Managerfrom flask_migrate import Migrate, MigrateCommandapp = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/appdb'db = SQLAlchemy(app)migrate = Migrate(app, db)manager = Manager(app)manager.add_command('db', MigrateCommand)class Post(db.Model): id = db.Column(db.Integer(), primary_key=True) post_text = db.Column(db.String(255)) def __init__(self, title, post_text): self.title = title self.post_text = post_text@app.route('/')def index(): return "Hello World"if __name__ == "__main__": manager.run()使用如下的命令初始化Alembic:
$ python app.py db initCreating directory /Users/Vihar/Desktop/flask-databases/migrations ... done.........Generating /Users/Vihar/Desktop/flask-databases/migrations/alembic.ini ... done
執(zhí)行第一個(gè)遷移任務(wù):
$ python app.py db migrateINFO [alembic.runtime.migration] Context impl PostgresqlImpl.INFO [alembic.runtime.migration] Will assume transactional DDL.INFO [alembic.autogenerate.compare] Detected added table 'post'Generating /Users/Vihar/Desktop/flask-databases/migrations/versions/ed3b3a028447_.py ... done
一旦上述命令執(zhí)行完畢,我們的數(shù)據(jù)表就會(huì)創(chuàng)建成功。現(xiàn)在更新數(shù)據(jù)庫(kù):
$ python app.py db upgrade
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。
新聞熱點(diǎn)
疑難解答
圖片精選