Flask框架下使用SQLAlchemy搭建用户类User来操纵数据库

在面向对象的编程语言(如 Python、Java、C# 等)中,使用类来表示用户信息是很常见的做法。例如,在 Python 的 Flask 或 Django 框架中,可以使用类来定义用户模型。而使用用户类在数据库中维护一个用户数据模型,可以有效地管理和持久化用户信息

在实际应用中,验证会话和用户类通常是结合使用的:

  1. 登录阶段:用户提交登录表单时,使用用户类验证用户的身份。
  2. 会话管理:验证成功后,使用会话存储用户标识符(如用户ID),在后续的请求中根据会话判断用户是否已登录。

User类示例(Python/Flask/SQLAlchemy):

定义模型类(指定表)

  • 每个模型类对应数据库中的一个表。

  • 模型类通过继承 db.Model 来指定表结构。

  • 每个类属性对应表中的一个字段。

    from flask_sqlalchemy import SQLAlchemy

    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
    db = SQLAlchemy(app) # 这里使用的是sqlite数据库,并指定使用的数据库为users

    class User(db.Model):
    tablename = 'users' # 显式指定表名,如果不指定,SQLAlchemy 会默认使用类名的小写形式作为表名
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)

User 模型的组件

  1. 数据库模型 : User 类继承自 db.Model,这表明它是一个 SQLAlchemy 模型,允许与数据库进行交互。

  2. 属性定义: 模型类通常定义一些属性,以表示用户数据在数据库表中的各个列。这些属性通过 SQLAlchemy 的列类型定义。

  3. 构造方法 : 可以定义一个构造函数 __init__,用于方便地创建 User 实例。

ORM:

这里需要介绍一下什么是ORM,不然读者可能不明白为什么能够使用用户类来实现对数据库的操作。ORM(对象关系映射)是一个用于处理数据库操作的技术,它允许开发者使用对象而不是 SQL 语言来操作数据库。而上面我们使用的SQLAlchemy 是一个流行的 Python ORM 框架。

在 Flask 应用中,class User(db.Model): 是定义一个用户模型的代码段。这个模型类通常用于与数据库交互,特别是使用 Flask-SQLAlchemy 这个扩展来管理数据库操作。下面是对User模型及其各个部分的详细解释,并附上完整的代码示例,展示如何定义和使用这个模型。

完整示例

以下是一个完整的 Flask 应用示例,包括定义用户模型 (User)、初始化数据库、用户注册和登录的逻辑。

复制代码
from flask import Flask, request, session, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
app.secret_key = 'your_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

# 定义 User 模型
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)  # 哈希后的密码

    def __repr__(self):
        return f'<User {self.username}>'

# 初始化数据库
with app.app_context():
    db.create_all()  # 创建数据库表

# 用户注册
@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        
        if User.query.filter_by(username=username).first():
            flash('Username already exists.')
            return redirect(url_for('register'))

        hashed_password = generate_password_hash(password, method='sha256')
        new_user = User(username=username, password=hashed_password)
        db.session.add(new_user)
        db.session.commit()
        
        flash('Registered successfully!')
        return redirect(url_for('login'))
    return '''
        <form method="post">
            Username: <input type="text" name="username"><br>
            Password: <input type="password" name="password"><br>
            <input type="submit" value="Register">
        </form>
    '''

# 用户登录
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        user = User.query.filter_by(username=username).first()
        if user and check_password_hash(user.password, password):
            session['user_id'] = user.id  # 将用户ID存入会话
            flash('Logged in successfully!')
            return redirect(url_for('profile'))
        else:
            flash('Invalid username or password.')
            return redirect(url_for('login'))
    return '''
        <form method="post">
            Username: <input type="text" name="username"><br>
            Password: <input type="password" name="password"><br>
            <input type="submit" value="Login">
        </form>
    '''

# 用户个人资料页面
@app.route('/profile')
def profile():
    if 'user_id' in session:
        user = User.query.get(session['user_id'])  # 获取当前用户的信息
        return f'Welcome, {user.username}!'
    return redirect(url_for('login'))

# 用户登出
@app.route('/logout')
def logout():
    session.pop('user_id', None)  # 清除会话
    flash('Logged out successfully!')
    return redirect(url_for('login'))

if __name__ == '__main__':
    app.run(debug=True)

解释代码部分

  • new_userUser 类的一个实例,而 User 类是 SQLAlchemy 模型的一部分。

  • db.session.add(new_user) 会将 new_user 对象添加到当前的 SQLAlchemy 会话中,SQLAlchemy 能够识别并跟踪这个对象。

  • 最终,通过 db.session.commit(),SQLAlchemy 会将 new_user 对象持存储到数据库中

  • user = User.query.filter_by(username=username).first() 这行代码的作用是从数据库的表中查询第一个 User 对象。因为在 ORM 中,数据库表被映射为类,表的每一行则被映射为类的一个实例(对象)。

  • 数据库设置:

    • 使用 SQLite 数据库,并配置数据库 URI。
    • db.Model 是 SQLAlchemy 提供的基础模型,User 类通过继承它来与数据库交互。
  • 注册和登录流程:

    • register 路由处理用户注册,首先检查用户名是否已经存在,然后将用户信息保存到数据库。
    • login 路由验证用户名和密码,如果验证成功,将用户 ID 存储在会话中,以维持登录状态。
  • 个人资料页面:

    • 检查用户是否已登录,如果已登录则显示用户信息,否则重定向到登录页。
相关推荐
怕什么真理无穷7 分钟前
mysql server 9.4 windows安装教程(sqlyog 下载)
数据库
Olrookie13 分钟前
MySQL运维常用SQL
运维·数据库·sql·mysql·dba
数据库生产实战23 分钟前
ORACLE 19C ADG环境 如何快速删除1.8TB的分区表?有哪些注意事项?
数据库·oracle
blackorbird40 分钟前
使用 Overpass Turbo 查找监控摄像头
运维·服务器·数据库·windows
IT永勇44 分钟前
SQLite数据库基本操作
数据库·sqlite·嵌入式开发·增删改查·关系型数据库
洋不写bug1 小时前
数据库的创建,查看,修改,删除,字符集编码和校验操作
android·数据库·adb
想ai抽1 小时前
吃透大数据算法-算法地图(备用)
大数据·数据库·spark
weixin_307779131 小时前
Clickhouse导出库的表、视图、用户和角色定义的SQL语句
开发语言·数据库·算法·clickhouse·自动化
流星白龙1 小时前
【Qt】7.信号和槽_connect函数用法(1)
开发语言·数据库·qt
码界奇点1 小时前
平替MongoDB金仓多模数据库在电子证照国产化中的实践与优势
数据库·mongodb·社交电子·里氏替代原则