Skip to content

模型创建

flask 一般是使用 flask-sqlalchemy 作为关系模型对象,编写代码,然后生成数据表。可以通过代码实现对数据表的修改,十分方便。

在切换数据库的时候,也只需要修改一下 URI 地址,就可以在 MySQL 与 sqlite 之间无缝切换。 在我们的课程里面,选择 MySQL 作为数据库,如果只是学习,SQLite 其实也够用了。

使用之间请确保对 flask-sqlalchemy 有一定了解,如果没有可以看我之前的文档 关系对象模型

创建数据模型

定义一个模型基类

python
from pear_admin.extensions import db


class BaseORM(db.Model):
    __abstract__ = True

    def save(self):
        db.session.add(self)
        db.session.commit()

    def delete(self):
        db.session.delete(self)
        db.session.commit()

封装部门类

python
import sqlalchemy as sa
from sqlalchemy.orm import relationship
from ._base import BaseORM


class DepartmentORM(BaseORM):
    __tablename__ = "ums_department"
    id = sa.Column(sa.Integer, primary_key=True, comment="部门ID")
    name = sa.Column(sa.String(50), comment="部门名称")
    leader = sa.Column(sa.String(50), comment="负责人")
    enable = sa.Column(sa.Boolean, comment="状态(1开启,0关闭)", default=True)

    pid = sa.Column(sa.Integer, sa.ForeignKey("ums_department.id"), default=1)

    def json(self):
        return {
            "id": self.id,
            "pid": self.pid,
            "name": self.name,
            "leader": self.leader,
            "enable": self.enable,
        }

封装 rights 权限类

python
import sqlalchemy as sa
from sqlalchemy.orm import relationship

from ._base import BaseORM


class RightsORM(BaseORM):
    __tablename__ = "ums_rights"

    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String(20), nullable=False, comment="权限名称")
    code = sa.Column(sa.String(30), comment="权限标识")
    type = sa.Column(sa.String(30), comment="权限类型")
    url = sa.Column(sa.String(30), comment="路径地址")

    icon_sign = sa.Column(sa.String(128), comment="图标")
    status = sa.Column(sa.Boolean, default=True, comment="是否开启")
    sort = sa.Column(sa.Integer, default=0)
    open_type = sa.Column(sa.String(128), comment="打开方式")
    pid = sa.Column(
        sa.Integer,
        sa.ForeignKey("ums_rights.id"),
        default=0,
        comment="父类编号",
    )

    def json(self):
        return {
            "id": self.id,
            "name": self.name,
            "code": self.code,
            "type": self.type,
            "url": self.url,
            "icon_sign": self.icon_sign,
            "status": self.status,
            "sort": self.sort,
            "open_type": self.open_type,
            "pid": self.pid,
        }

    def menu_json(self):
        type_map_dict = {"menu": 0, "path": 1}

        return {
            "id": self.id,
            "pid": self.pid,
            "title": self.name,
            "type": type_map_dict[self.type],
            "href": self.url,
            "icon": self.icon_sign,
            "sort": self.sort,
            "openType": self.open_type,
        }

封装角色类

python
import sqlalchemy as sa
from sqlalchemy.orm import relationship, backref
from ._base import BaseORM


class RoleORM(BaseORM):
    __tablename__ = "ums_role"

    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String(20), nullable=False, comment="角色名称")
    code = sa.Column(sa.String(20), nullable=False, comment="角色标识符")
    desc = sa.Column(sa.Text)

    rights_ids = sa.Column(
        sa.String(512),
        comment="权限ids,1,2,5。冗余字段,用户缓存用户权限",
    )

    def json(self):
        return {
            "id": self.id,
            "name": self.name,
            "code": self.code,
            "desc": self.desc,
            "rights_ids": self.rights_ids,
        }

封装用户类

python
from datetime import datetime
import sqlalchemy as sa
from sqlalchemy.orm import relationship, backref

from werkzeug.security import check_password_hash, generate_password_hash

from ._base import BaseORM


class UserORM(BaseORM):
    __tablename__ = "ums_user"

    id = sa.Column(sa.Integer, primary_key=True, comment="自增id")
    nickname = sa.Column(sa.String(128), nullable=False, comment="昵称")
    username = sa.Column(sa.String(128), nullable=False, comment="登录名")
    password_hash = sa.Column(sa.String(102), nullable=False, comment="登录密码")
    mobile = sa.Column(sa.String(32), nullable=False, comment="手机")
    email = sa.Column(sa.String(64), nullable=False, comment="邮箱")
    avatar = sa.Column(sa.Text, comment="头像地址")
    create_at = sa.Column(
        sa.DateTime,
        nullable=False,
        comment="创建时间",
        default=datetime.now,
    )
    department_id = sa.Column(
        sa.Integer, sa.ForeignKey("ums_department.id"), default=1, comment="部门id"
    )

    def json(self):
        return {
            "id": self.id,
            "username": self.username,
            "nickname": self.nickname,
            "mobile": self.mobile,
            "email": self.email,
            "create_at": self.create_at.strftime("%Y-%m-%d %H:%M:%S"),
        }

    @property
    def password(self):
        return self.password_hash

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password=password)

关系表创建

python
from pear_admin.extensions import db
import sqlalchemy as sa

from .department import DepartmentORM
from .rights import RightsORM
from .role import RoleORM
from .user import UserORM

user_role = sa.Table(
    "ums_user_role",  # 用户-角色中间表名称
    db.metadata,
    sa.Column("id", sa.Integer, primary_key=True, autoincrement=True, comment="标识"),
    sa.Column("user_id", sa.Integer, sa.ForeignKey("ums_user.id"), comment="用户编号"),
    sa.Column("role_id", sa.Integer, sa.ForeignKey("ums_role.id"), comment="角色编号"),
)

role_rights = sa.Table(
    "ums_role_rights",  # 用户-权限中间表名称
    db.metadata,
    sa.Column("id", sa.Integer, primary_key=True, autoincrement=True, comment="标识"),
    sa.Column("rights_id", sa.Integer, sa.ForeignKey("ums_rights.id"), comment="用户编号"),
    sa.Column("role_id", sa.Integer, sa.ForeignKey("ums_role.id"), comment="角色编号"),
)

添加关系

也就是 relationship

部门关系

python
import sqlalchemy as sa
from sqlalchemy.orm import relationship
from ._base import BaseORM


class DepartmentORM(BaseORM):
    __tablename__ = "ums_department"
    id = sa.Column(sa.Integer, primary_key=True, comment="部门ID")
    name = sa.Column(sa.String(50), comment="部门名称")
    leader = sa.Column(sa.String(50), comment="负责人")
    enable = sa.Column(sa.Boolean, comment="状态(1开启,0关闭)", default=True)

    users = relationship("UserORM", backref="department")

    pid = sa.Column(sa.Integer, sa.ForeignKey("ums_department.id"), default=1)

    parent = relationship(  # //[!code ++]
        "DepartmentORM", back_populates="children", remote_side=[id]  # //[!code ++]
    )  # 自关联 //[!code ++]
    children = relationship("DepartmentORM", back_populates="parent")  # //[!code ++]

权限关系

python
import sqlalchemy as sa
from sqlalchemy.orm import relationship

from ._base import BaseORM


class RightsORM(BaseORM):
    __tablename__ = "ums_rights"

    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String(20), nullable=False, comment="权限名称")
    code = sa.Column(sa.String(30), comment="权限标识")
    type = sa.Column(sa.String(30), comment="权限类型")
    url = sa.Column(sa.String(30), comment="路径地址")

    icon_sign = sa.Column(sa.String(128), comment="图标")
    status = sa.Column(sa.Boolean, default=True, comment="是否开启")
    sort = sa.Column(sa.Integer, default=0)
    open_type = sa.Column(sa.String(128), comment="打开方式")
    pid = sa.Column(
        sa.Integer,
        sa.ForeignKey("ums_rights.id"),
        default=0,
        comment="父类编号",
    )

    parent = relationship(  # //[!code ++]
        "RightsORM", back_populates="children", remote_side=[id]  # //[!code ++]
    )  # 自关联  //[!code ++]
    children = relationship("RightsORM", back_populates="parent")  # //[!code ++]

角色关系

python
import sqlalchemy as sa
from sqlalchemy.orm import relationship, backref
from ._base import BaseORM


class RoleORM(BaseORM):
    __tablename__ = "ums_role"

    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String(20), nullable=False, comment="角色名称")
    code = sa.Column(sa.String(20), nullable=False, comment="角色标识符")
    desc = sa.Column(sa.Text)

    rights_ids = sa.Column(
        sa.String(512),
        comment="权限ids,1,2,5。冗余字段,用户缓存用户权限",
    )

    rights_list = relationship(  # //[!code ++]
        "RightsORM", secondary="ums_role_rights", backref=backref("role")  # //[!code ++]
    )  # //[!code ++]

用户关系

python
from datetime import datetime
import sqlalchemy as sa
from sqlalchemy.orm import relationship, backref

from ._base import BaseORM


class UserORM(BaseORM):
    __tablename__ = "ums_user"

    id = sa.Column(sa.Integer, primary_key=True, comment="自增id")
    nickname = sa.Column(sa.String(128), nullable=False, comment="昵称")
    username = sa.Column(sa.String(128), nullable=False, comment="登录名")
    password_hash = sa.Column(sa.String(102), nullable=False, comment="登录密码")
    mobile = sa.Column(sa.String(32), nullable=False, comment="手机")
    email = sa.Column(sa.String(64), nullable=False, comment="邮箱")
    avatar = sa.Column(sa.Text, comment="头像地址")
    create_at = sa.Column(
        sa.DateTime,
        nullable=False,
        comment="创建时间",
        default=datetime.now,
    )
    department_id = sa.Column(
        sa.Integer, sa.ForeignKey("ums_department.id"), default=1, comment="部门id"
    )

    role_list = relationship(  # //[!code ++]
        "RoleORM",  # //[!code ++]
        secondary="ums_user_role",  # //[!code ++]
        backref=backref("user"),  # //[!code ++]
        lazy="dynamic",  # //[!code ++]
    )  # //[!code ++]