Flask框架是Python開發(fā)的一個基于Werkzeug和Jinja 2的web開發(fā)微框架顿锰,它的優(yōu)勢就是極其簡潔,但又非常靈活,而且容易學習和應用进泼。因此Flask框架是Python新手快速開始web開發(fā)最好的選擇,此外纤虽,使用Flask框架的另一個好處在于你可以非常輕松地將基于Python的機器學習算法或數(shù)據(jù)分析算法集成到web應用中乳绕。
如果希望深入學習Flask Web開發(fā),推薦這個教程:
深入淺出Flask
1逼纸、可以用Flask框架做什么
從博客應用到克隆一個facebook或者twitter洋措,理論上你可以用Flask做任何事情。有很多庫可以直接使用杰刽,例如flask-sockets菠发,flask-google-maps等,而且Flask框架支持MySQL贺嫂、Postgresql滓鸠、MongoDB等諸多數(shù)據(jù)庫。
我能想到的一些可以用Flask框架實現(xiàn)的web應用類型:博客應用第喳、聊天應用糜俗、儀表盤應用、RESTAPI曲饱、管理頁面悠抹、郵件服務等。
安裝Flask
使用pip安裝Flask:
$ pip install flask
2扩淀、Hello,World
創(chuàng)建一個文件app.py楔敌,然后只需要幾個簡單的步驟,就可以寫出Flask版本的Hello World
- 引入Flask類
from flask import Flask
- 創(chuàng)建Flask對象驻谆,我們將使用該對象進行應用的配置和運行:
app = Flask(__name__)
name 是Python中的特殊變量卵凑,如果文件作為主程序執(zhí)行庆聘,那么__name__
變量的值就是__main__
,如果是被其他模塊引入勺卢,那么__name__
的值就是模塊名稱掏觉。
- 編寫主程序
在主程序中,執(zhí)行run()
來啟動應用:
if __name__ =="__main__":
app.run(debug=True, port=8080)
改名啟動一個本地服務器值漫,默認情況下其地址是localhost:5000
澳腹,在上面的代碼中,我們使用關(guān)鍵字參數(shù)port
將監(jiān)聽端口修改為8080杨何。
- 路由
使用app變量的route()
裝飾器來告訴Flask框架URL如何觸發(fā)我們的視圖函數(shù):
@app.route('/')
def hello_world():
return 'Hello, World!'
上面的標識酱塔,對路徑'/'的請求,將轉(zhuǎn)為對hello_world()
函數(shù)的調(diào)用危虱。很直白羊娃,對吧?
- 運行
現(xiàn)在埃跷,讓我們完整地看一下app.py的整個代碼:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ =="__main__":
app.run(debug=True,port=8080)
然后運行起來:
$ python app.py
你應該會看到如下輸入:
* 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
現(xiàn)在就可以打開瀏覽器訪問http://127.0.0.1:8080/
了:
3蕊玷、使用HTML模板
首先我們看看如何原始的HTML代碼插入Flask應用:
from flask import Flask
app = 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字符串來展示user字典的數(shù)據(jù)∶直ⅲ現(xiàn)在訪問http://127.0.0.1:8080/greet
:
拼接HTML字符串非常容易出錯垃帅,因此Flask使用Jinja 2模板引擎來分離數(shù)據(jù)邏輯和展示層。
我們將模板文件按如下路徑放置:
Apps folder
/app.py
templates
|-/index.html
使用模板時剪勿,視圖函數(shù)應當返回render_template()
的調(diào)用結(jié)果贸诚。例如下面的代碼片段渲染模板index.html
,并將渲染結(jié)果作為視圖函數(shù)的返回值:
from flask import Flask, render_template
app = 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>
模板文件的語法擴充了HTML,因此可以使用變量和邏輯头朱。
在瀏覽器中訪問http://127.0.0.1:8080/hello/alex
:
4运悲、使用表單
每個web應用都需要使用表單來采集用戶數(shù)據(jù)。現(xiàn)在讓我們使用Flask框架創(chuàng)建一個簡單的表單來收集用戶的基本信息项钮,例如名稱班眯、年齡、郵件寄纵、興趣愛好等鳖敷,我們將這個模板文件命名為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
同時支持POST和GET請求。GET請求將渲染bio_form.html
模板程拭,而POST請求將重定向到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的實現(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ù)庫集成:使用SQLAlchemy
Flask不能直接連接數(shù)據(jù)庫棍潘,需要借助于ORM(Object Relational Mapper)恃鞋。在這一部分崖媚,我們將借助于SQLAlchemy使用Postgres數(shù)據(jù)庫。
- 安裝Flask-SQLAlchemy和Postgres
首先安裝flask-sqlalchemy:
$ pip install flask-sqlalchemy
然后從官方下載并安裝postgres:https://postgresapp.com/
- 創(chuàng)建數(shù)據(jù)庫
在終端中使用下面的命令創(chuàng)建一個appdb數(shù)據(jù)庫:
$ createdb appdb
- 更新應用配置
修改app.config恤浪,添加數(shù)據(jù)庫相關(guān)的配置信息:
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI']='postgresql://localhost/appdb'
SQLALCHEMY_TRACK_MODIFICATIONS = True
db = SQLAlchemy(app)
然后在代碼中就可以使用這些配置數(shù)據(jù)了:
from flask import Flask, request, render_template
from flask_sqlalchemy import SQLAlchemy
# Settings
app = Flask(__name__)
app.config['DEBUG'] = True
app.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)建第一個模型(Model)。所有模型的基類是db.Model水由,使用Column來定義數(shù)據(jù)列:
class Post(db.Model):
id = db.Column(db.Integer(), primary_key=True)
title = db.Column(db.String(80), unique=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 Flask
from flask_sqlalchemy import SQLAlchemy
app = 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)
title = db.Column(db.String(80), unique=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時,需要執(zhí)行遷移操作以便在模型和持久化數(shù)據(jù)之間保持同步砂客。我們使用Flask-Migrate這個擴展來完成該任務泥张。
首先安裝:
$ pip install flask-migrate
$ pip install flask_script
然后在代碼中引入:
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
進行必要的配置:
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
運行管理器:
if __name__ == '__main__':
manager.run()
完整的代碼如下:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
app = 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)
title = db.Column(db.String(80), unique=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 init
Creating directory /Users/Vihar/Desktop/flask-databases/migrations ... done
...
...
...
Generating /Users/Vihar/Desktop/flask-databases/migrations/alembic.ini ... done
執(zhí)行第一個遷移任務:
$ python app.py db migrate
INFO [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ù)表就會創(chuàng)建成功【现担現(xiàn)在更新數(shù)據(jù)庫:
$ python app.py db upgrade
匯智網(wǎng)翻譯整理媚创,轉(zhuǎn)載請標明出處。原文鏈接:Flask框架web開發(fā):零基礎入門