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 存储在会话中,以维持登录状态。
  • 个人资料页面:

    • 检查用户是否已登录,如果已登录则显示用户信息,否则重定向到登录页。
相关推荐
企鹅侠客2 分钟前
ETCD调优
数据库·etcd
Json_181790144808 分钟前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
煎饼小狗20 分钟前
Redis五大基本类型——Zset有序集合命令详解(命令用法详解+思维导图详解)
数据库·redis·缓存
永乐春秋36 分钟前
WEB-通用漏洞&SQL注入&CTF&二次&堆叠&DNS带外
数据库·sql
打鱼又晒网1 小时前
【MySQL】数据库精细化讲解:内置函数知识穿透与深度学习解析
数据库·mysql
大白要努力!1 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
tatasix2 小时前
MySQL UPDATE语句执行链路解析
数据库·mysql
南城花随雪。2 小时前
硬盘(HDD)与固态硬盘(SSD)详细解读
数据库
儿时可乖了2 小时前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
懒是一种态度2 小时前
Golang 调用 mongodb 的函数
数据库·mongodb·golang