Flask 通过SQLAlchemy连接mySQL实现一个实用的用户管理功能
安装配置
首先确保已经安装如下程序:
- flask:用于构建web应用程序。
- flask-sqlalchemy:用于在 Flask 中连接 MySQL 数据库,通过
pip install flask-sqlalchemy
安装。 - pymysql:运行时可能会出现出现 ModuleNotFoundError: No module named ‘MySQLdb’ 错误,通常是由于缺少 MySQL Python 驱动程序导致的。这里我使用的是 PyMySQL 作为 MySQL 的连接器,通过
pip install pymysql
安装后,在连接数据库时将连接字符串中的 mysql 替换为 mysql+pymysql即可。
配置数据库连接信息,并创建 SQLAlchemy 用户对象
在配置文件模块config.py中,配置 数据库连接信息,并创建 SQLAlchemy 用户对象,这样就可以在其他地方直接引用:
# config.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy() # 创建全局的 SQLAlchemy 实例def create_app():app = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://username:password@localhost/db_name'app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Falsedb.init_app(app) # 在应用工厂函数中初始化 SQLAlchemy 实例return appclass User(db.Model):id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(50), unique=True, nullable=False)nickname = db.Column(db.String(50), nullable=False)password = db.Column(db.String(50), nullable=False)
注意,在app.config[‘SQLALCHEMY_DATABASE_URI’] = 'mysql+pymysql://username:password@localhost/db_name’中要将对应的数据库用户名、密码、地址、表名换成自己数据的真实信息。
编写 routers.py 路由模块
在 routers.py 文件中,编写用户列表、新增用户、删除用户接口
# routers.py
from flask import Blueprint, render_template,request,redirect,url_for,jsonify
from config import db,User # 导入应用工厂函数中初始化的 SQLAlchemy 实例bp = Blueprint('main', __name__)@bp.route('/')
def index():# 打开数据库连接db.create_all()# 查询所有用户users = User.query.all()# 关闭数据库连接db.session.close()return render_template('users.html',users=users)@bp.route('/add',methods=['GET'])
def add():return render_template('addUser.html')@bp.route('/add_user', methods=['POST'])
def add_user():# 打开数据库连接db.create_all()# 获取请求数据data = request.get_json()username = data.get('username')nickname = data.get('nickname')password = data.get('password')# 创建新用户new_user = User(username=username, nickname=nickname, password=password)print(new_user)db.session.add(new_user)db.session.commit()# 关闭数据库连接db.session.close()return 'User added successfully'# return redirect(url_for('main.index'))@bp.route('/del_user', methods=['POST'])
def del_user():# 打开数据库连接db.create_all()# 获取请求数据data = request.get_json()username = data.get('username')user = User.query.filter_by(username={username}).first()print(user)if user:# 删除用户db.session.delete(user)db.session.commit()# 关闭数据库连接db.session.close()return 'User added successfully'# return redirect(url_for('main.index')) 在else:return 'User not found'def init_routes(app):app.register_blueprint(bp)
这里我使用了 Blueprint 编写路由,便于后期项目管理,也可以不使用。注意,在 Blueprint 中要实现路由跳转,需要写return redirect(url_for('main.index'))
,如果写成return redirect(url_for('index'))
将无法跳转。
用户列表 html 页面
用户列表页面:users.html代码如下
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>用户列表</title>
</head>
<body><h2>用户列表</h2><ul>{% for user in users %}<li>{{user.username}}-{{user.nickname}} <button onclick="delUser('{{user.username}}')">删除用户</button></li>{% endfor %}</ul><a href="http://localhost:5000/add">新增用户</a><script>function delUser(username) {fetch('/del_user', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ username: username })}).then(response => {console.log(response);if (response.ok) {// 请求成功,重定向到首页,从而刷新页面window.location.href = '/';} else {alert('删除用户失败');}})}</script></body>
</html>
新增用户 html 页面
新增用户页面:addUser.html代码如下
<html lang="en"><head><meta charset="UTF-8"><title>Login</title>
</head>
<body><form><h2>新增用户</h2><table><tr><td>Username</td><td><input type="text" name="username" id="username"></td></tr><tr><td>Nickname</td><td><input type="text" name="nickname" id="nickname"></td></tr><tr><td>Password</td><td><input type="password" name="password" id="password"></td></tr><tr><td><button onclick="addUser()">提交</button></td></tr><tr><td><a href="http://localhost:5000/">查看用户列表</a></td></tr></table></form><script>function addUser() {var username = document.getElementById('username').value;var nickname = document.getElementById('nickname').value;var password = document.getElementById('password').value;var data = {username: username,nickname: nickname,password: password};if (username && nickname && password) {fetch('/add_user', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify(data)}).then(response => {if (response.ok) {alert('新增用户成功');// 请求成功,重定向到首页,从而刷新页面,视需求而定// window.location.href = '/';} else {alert('新增用户失败');}})} else {alert('请输入表单信息');}}</script>
</body>
</html>
编写 main.py 主程序
最后,在主程序 main.py 中,引入对应模块,并注入app中
# main.py
from config import create_app, db
from routes import init_routes# 调用应用工厂函数创建应用实例
app = create_app()init_routes(app)if __name__ == '__main__':app.run(debug=True)
运行,预览效果
运行 main.py 文件,可以看到