使用 Flask 構建 Web 應用程序:完整實戰教程

Flask 是一個用 Python 編寫的 Web 應用程序框架。它被設計成靈活和易于擴展,讓開發人員能夠快速構建出高性能的 Web 應用程序。在這里,我們將介紹如何使用 Flask 構建一個完整的 Web 應用程序,包括使用 Flask-RESTful 構建 RESTful API、使用 Flask-SQLAlchemy 進行數據庫操作、使用 Flask-wtf 進行表單驗證和使用 Flask-JWT 進行身份認證和授權。
1、使用 Flask 構建 Web 應用程序
首先,我們需要安裝 Flask。可以使用 pip 命令進行安裝:
pip install flask在我們開始構建應用程序之前,我們需要導入 Flask:
from flask import Flask接下來,我們需要創建一個 Flask 應用程序實例:
app = Flask(__name__)現在我們可以開始定義路由了。路由是 Web 應用程序中用于處理 HTTP 請求的函數。我們可以使用 @app.route() 裝飾器來定義路由:
@app.route('/')
def hello_world():
return 'Hello, World!'在這個例子中,我們定義了一個路由 /,當用戶訪問這個路由時,hello_world 函數會被調用,然后它會返回一個字符串 Hello, World!。我們可以通過運行以下命令來啟動這個應用程序:
if __name__ == '__main__':
app.run()這個命令會啟動一個本地服務器,并且會監聽 http://127.0.0.1:5000/ 這個地址。現在,如果我們在瀏覽器中訪問這個地址,我們就可以看到 Hello, World! 這個字符串了。
2、使用 Flask-RESTful 構建 RESTful API
Flask-RESTful 是一個為 Flask 提供 RESTful API 支持的擴展。它可以讓我們更輕松地構建出符合 RESTful API 規范的 API。
我們可以使用 pip 命令進行安裝:
pip install flask-restful在使用 Flask-RESTful 之前,我們需要先導入它:
from flask_restful import Resource, Api然后,我們需要創建一個 API 實例:
api = Api(app)現在我們可以開始定義 RESTful API 了。我們可以通過繼承 Resource 類來定義一個資源,然后將這個資源注冊到 API 實例中。
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(HelloWorld, '/hello')在這個例子中,我們定義了一個名為 HelloWorld 的資源,它支持 GET 請求,并且返回一個 JSON 格式的數據 {'hello': 'world'}。我們可以通過訪問 /hello 這個路由來獲取這個數據。
3、使用 Flask-SQLAlchemy 進行數據庫操作
Flask-SQLAlchemy 是一個為 Flask 提供 SQL 數據庫支持的擴展。它可以讓我們更輕松地使用 SQL 數據庫進行數據存儲和查詢。
我們可以使用 pip 命令進行安裝:
pip install flask-sqlalchemy在使用 Flask-SQLAlchemy 之前,我們需要先導入它:
from flask_sqlalchemy import SQLAlchemy然后,我們需要創建一個 SQLAlchemy 實例:
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)在這個例子中,我們配置了一個 SQLite 數據庫,文件名為 example.db。
現在我們可以開始定義模型了。模型是指數據庫中的表結構,它用于存儲數據和進行查詢。我們可以通過繼承 db.Model 類來定義一個模型。
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
email = db.Column(db.String(120), nullable=False, unique=True)在這個例子中,我們定義了一個名為 User 的模型,它有一個 id 字段、一個 name 字段和一個 email 字段。id 字段是主鍵,并且它是一個自增的整數。name 字段和 email 字段分別是一個字符串類型,長度分別為 80 和 120,它們都不能為空,并且 email 字段必須是唯一的。
現在我們可以通過這個模型來進行數據操作了。例如,我們可以通過以下代碼來添加一個新的用戶:
user = User(name='John', email='john@example.com')
db.session.add(user)
db.session.commit()這個代碼會創建一個名為 John 的用戶,并將它保存到數據庫中。
4、使用 Flask-WTF 進行表單驗證
Flask-wtf 是一個為 Flask 提供表單驗證支持的擴展。它可以讓我們更輕松地進行表單驗證和錯誤處理。
我們可以使用 pip 命令進行安裝:
pip install flask-wtf在使用 Flask-wtf 之前,我們需要先導入它:
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired然后,我們需要創建一個表單類:
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = StringField('Password', validators=[DataRequired()])
submit = SubmitField('Login')在這個例子中,我們定義了一個名為 LoginForm 的表單類,它有一個 username 字段、一個 password 字段和一個 submit 字段。username 字段和 password 字段都是字符串類型,并且不能為空。submit 字段是一個提交按鈕。
現在我們可以在路由函數中使用這個表單了:
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
# 處理表單提交的數據
username = form.username.data
password = form.password.data
# 進行身份認證
if authenticate(username, password):
# 如果認證成功,將用戶保存到 session 中
session['username'] = username
# 跳轉到首頁
return redirect(url_for('index'))
else:
# 如果認證失敗,顯示錯誤信息
flash('Invalid username or password')
# 渲染表單頁面
return render_template('login.html', form=form)在這個例子中,我們定義了一個名為 login 的路由函數,它處理 GET 和 POST 請求。在 GET 請求中,它渲染一個名為 login.html 的模板,并將 LoginForm 類傳遞給模板。在 POST 請求中,它首先驗證表單數據是否合法,如果合法,則進行身份認證,如果認證成功,則將用戶保存到 session 中,并跳轉到首頁;如果認證失敗,則顯示錯誤信息。
5、使用 Flask-JWT 進行身份認證和授權
Flask-JWT 是一個為 Flask 提供身份認證和授權支持的擴展。它可以讓我們更輕松地進行用戶認證和權限控制。
我們可以使用 pip 命令進行安裝:
pip install flask-jwt在使用 Flask-JWT 之前,我們需要先導入它:
from flask_jwt import JWT, jwt_required, current_identity
from werkzeug.security import safe_str_cmp然后,我們需要定義一個認證函數和一個回調函數:
def authenticate(username, password):
user = User.query.filter_by(username=username).first()
if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
return user
def identity(payload):
user_id = payload['identity']
return User.query.get(user_id)在這個例子中,我們定義了一個名為 authenticate 的認證函數和一個名為 identity 的回調函數。認證函數接收一個用戶名和密碼,然后在數據庫中查找用戶,如果用戶存在并且密碼正確,則返回該用戶;否則返回 None。回調函數接收一個 JWT 載荷,然后根據載荷中的用戶 ID 查找用戶,并返回該用戶。
現在我們可以使用這些函數來配置 JWT:
app.config['JWT_SECRET_KEY'] = 'secret'
jwt = JWT(app, authenticate, identity)在這個例子中,我們配置了一個 JWT 密鑰,然后創建了一個 JWT 實例。
現在我們可以在路由函數中使用 jwt_required 裝飾器來限制訪問權限:
@app.route('/protected')
@jwt_required()
def protected():
return f'Hello, {current_identity.username}!'在這個例子中,我們定義了一個名為 protected 的路由函數,并使用 jwt_required 裝飾器限制了訪問權限。如果用戶未登錄或者 JWT 驗證失敗,則會返回一個錯誤響應;如果驗證成功,則可以在函數中訪問 current_identity 對象來獲取當前用戶的信息。
完整的代碼示例:
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired
from werkzeug.security import generate_password_hash, check_password_hash
from flask_jwt import JWT, jwt_required, current_identity
from datetime import timedelta
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SECRET_KEY'] = 'secret'
app.config['JWT_AUTH_URL_RULE'] = '/login'
app.config['JWT_EXPIRATION_DELTA'] = timedelta(hours=1)
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password = db.Column(db.String(120), nullable=False)
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Log In')
def authenticate(username, password):
user = User.query.filter_by(username=username).first()
if user and check_password_hash(user.password, password):
return user
def identity(payload):
user_id = payload['identity']
return User.query.get(user_id)
app.config['JWT_SECRET_KEY'] = 'secret'
jwt = JWT(app, authenticate, identity)
@app.route('/')
def index():
return 'Hello, World!'
@app.route('/protected')
@jwt_required()
def protected():
return f'Hello, {current_identity.username}!'
@app.route('/users', methods=['GET'])
@jwt_required()
def get_users():
users = User.query.all()
return jsonify([{'id': user.id, 'username': user.username} for user in users])
@app.route('/users', methods=['POST'])
def create_user():
data = request.get_json()
username = data.get('username')
password = data.get('password')
if not username or not password:
return jsonify({'error': 'username and password are required'}), 400
user = User.query.filter_by(username=username).first()
if user:
return jsonify({'error': 'username already exists'}), 400
user = User(username=username, password=generate_password_hash(password))
db.session.add(user)
db.session.commit()
return jsonify({'id': user.id, 'username': user.username}), 201
if __name__ == '__main__':
app.run(debug=True)在這個例子中,我們定義了一個名為 User 的模型類,并在數據庫中創建了一個名為 example.db 的 SQLite 數據庫。我們還定義了一個名為 LoginForm 的表單類,用于驗證用戶登錄表單的數據。
我們使用 Flask-JWT 實現了身份認證和授權功能,使用了 jwt_required 裝飾器來限制訪問權限。我們還實現了兩個 API:/users 和 /protected。/users API 支持 GET 和 POST 方法,用于獲取所有用戶信息和創建新用戶。/protected API 僅支持 GET 方法,用于演示如何使用 JWT 認證和授權功能保護 API。
在我們的應用程序中,我們使用 Flask-SQLAlchemy 進行數據庫操作,使用 Flask-wtf 進行表單驗證。這些擴展都是 Flask 生態系統中非常流行的擴展,可以讓我們輕松地創建和操作 Web 應用程序。
值得注意的是,我們在應用程序中使用了 Flask-JWT 進行身份認證和授權,JWT 是一種輕量級的身份驗證和授權方案,可以很容易地實現基于 token 的身份驗證和授權。在我們的應用程序中,我們使用 JWT 生成 token,并使用 jwt_required 裝飾器限制了訪問權限。在實際的應用程序中,您可以根據需要調整 JWT 的配置,并根據實際需求來限制訪問權限。
在編寫 Flask 應用程序時,您還可以使用其他的 Flask 擴展來擴展應用程序的功能。例如,您可以使用 Flask-Mail 擴展來發送電子郵件,使用 Flask-Admin 擴展來創建管理員界面等等。在選擇擴展時,建議選擇流行度較高、維護活躍的擴展,并根據實際需求進行選擇。
希望這個示例可以幫助您更好地理解如何使用 Flask 構建 Web 應用程序,并使用一些流行的擴展來擴展應用程序的功能。如果您有任何疑問或建議,請隨時在評論中留言,我會盡力回答您的問題。
























