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 SQLAlchemy
db = 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'] = False
db.init_app(app) # 在应用工厂函数中初始化 SQLAlchemy 实例
return app
class 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 文件,可以看到