使用 Flask 构建 Web 应用程序:完整实战教程
wptr33 2025-04-24 09:21 22 浏览
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 应用程序,并使用一些流行的扩展来扩展应用程序的功能。如果您有任何疑问或建议,请随时在评论中留言,我会尽力回答您的问题。
每天坚持学习一点点,不求有回报,只愿可以丰富自己!!!
相关推荐
- MySQL进阶五之自动读写分离mysql-proxy
-
自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...
- 3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?
-
引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...
- 一文由浅入深带你完全掌握MySQL的锁机制原理与应用
-
本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...
- 验证Mysql中联合索引的最左匹配原则
-
后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...
- MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)
-
目录1.索引基础...
- 你会看 MySQL 的执行计划(EXPLAIN)吗?
-
SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...
- MySQL 从入门到精通(四)之索引结构
-
索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...
- mysql总结——面试中最常问到的知识点
-
mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...
- mysql总结——面试中最常问到的知识点(2)
-
首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...
- MySQL基础全知全解!超详细无废话!轻松上手~
-
本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...
- 深入剖析 MySQL 中的锁机制原理_mysql 锁详解
-
在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...
- Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析
-
引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...
- MySQL基础篇:DQL数据查询操作_mysql 查
-
一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...
- MySql:索引的基本使用_mysql索引的使用和原理
-
一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
程序员的开源月刊《HelloGitHub》第 71 期
-
详细介绍一下Redis的Watch机制,可以利用Watch机制来做什么?
-
假如有100W个用户抢一张票,除了负载均衡办法,怎么支持高并发?
-
如何将AI助手接入微信(打开ai手机助手)
-
Java面试必考问题:什么是乐观锁与悲观锁
-
SparkSQL——DataFrame的创建与使用
-
redission YYDS spring boot redission 使用
-
一文带你了解Redis与Memcached? redis与memcached的区别
-
如何利用Redis进行事务处理呢? 如何利用redis进行事务处理呢英文
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)