前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Flask 表结构 用户权限划分

Flask 表结构 用户权限划分

作者头像
Python之道
发布于 2020-06-02 07:15:38
发布于 2020-06-02 07:15:38
1.3K00
代码可运行
举报
文章被收录于专栏:程序员八阿哥程序员八阿哥
运行总次数:0
代码可运行

Flask 用户权限划分

最近学习了下用户权限划分的数据库结构,并且结合到了 Flask 和 SQLAlchemy 中

  • [基础表]
    • [用户表]
    • [角色表]
    • [权限表]
    • [菜单表]
  • [关联表]
    • [用户角色表]
    • [角色权限表]
    • [角色菜单表]
  • [SQLAlchemy]
  • [与 Flask 结合]

首先是数据库的整体结构图(简化版)

权限

基础表#### 用户表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UserModel(db.Model):
    __tablename__ = 'user'
    username = db.Column(db.String(50))
    password = db.Column(db.String(128))
    email = db.Column(db.String(128))
    mobile = db.Column(db.String(11))
    name = db.Column(db.String(50))
    gender = db.Column(db.SmallInteger)  # 0 未知, 12
角色表
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class RoleModel(db.Model):
    __tablename__ = 'role'
    name = db.Column(db.String(20))
权限表
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class PermissionModel(db.Model):
    __tablename__ = 'permission'
    name = db.Column(db.String(50))
    action = db.Column(db.String(250), unique=True)
菜单表
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MenuModel(db.Model):
    __tablename__ = 'menu'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    icon = db.Column(db.String(50))
    url = db.Column(db.String(250))
    order = db.Column(db.SmallInteger, default=0)
    bg_color = db.Column(db.String(50))

关联表

基础表完了就是关联表了

用户角色表

用户跟角色,肯定是多对多的关系,按照 Flask-SQLAlchemy 里的 Many-to-Many Relationships

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
user_role = db.Table('user_role',  # 用户角色关联表
    db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
    db.Column('role_id', db.Integer, db.ForeignKey('role.id')),
    db.Column('created_at', db.DateTime, default=datetime.now),
)
角色权限表

这里把权限挂在了角色下面,其实也可以去掉角色,直接跟用户挂钩,但是如果后期在后台分配用户权限,估计会累死。这里角色跟权限也是多对多

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
role_permission = db.Table('role_permission',  # 角色权限关联表
    db.Column('permission_id', db.Integer, db.ForeignKey('permission.id')),
    db.Column('role_id', db.Integer, db.ForeignKey('role.id')),
    db.Column('created_at', db.DateTime, default=datetime.now),
)
角色菜单表

同上,也是多对多

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
role_menu = db.Table('role_menu',  # 用户菜单关联表
    db.Column('role_id', db.Integer, db.ForeignKey('role.id')),
    db.Column('menu_id', db.Integer, db.ForeignKey('menu.id')),
    db.Column('created_at', db.DateTime, default=datetime.now),
    db.Column('is_delete', db.Boolean, default=False),
)

SQLAlchemy

如果需要获取一个用户的角色,可以利用relationship,关联到角色表上

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UserModel(db.Model):
    # ...
    roles = db.relationship(
        'RoleModel',
        secondary=user_role,
        backref=db.backref(
            'users',
            lazy='dynamic'
        )
    )

获取用户的所有权限可以用property

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UserModel(db.Model):
    # ...
    @property
    def permissions(self):
        permissions = PermissionModel.query.join(role_permission).join(RoleModel).join(user_role).join(UserModel).\
            filter(
            UserModel.id == self.id
        )
        return permissions

同理菜单

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UserModel(db.Model):
    # ...
    @property
    def menus(self):
        menus = MenuModel.query.join(role_menu).join(RoleModel).join(user_role).join(UserModel).\
            filter(
            UserModel.id == self.id
        ).order_by(MenuModel.type_, MenuModel.order).all()
        return menus

这样就可以用user.permissionsuser.menus来获得用户的权限和菜单了

与 Flask 结合

数据库表结构设计好了,下面就是跟 Flask 的结合了

Python 中,用 decorator 可以用来做用户验证,比如下面

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def auth(method):
    @functools.wraps(method)
    def wrapper(*args, **kwargs):
        user_id = session.get('user_id')
        if not user_id:
            return abort(403)
        return method(*args, **kwargs)
    return wrapper

@app.router('/user/info')
@auth
def user_info():
    return render_template('user/info.html')

上面就是利用 Python 的 decorator 来认证用户,其实也是简单的权限划分

因为在 Flask 中,每个 view 就是一个函数,所以在权限表中,用action来表示每个 view 的函数名,那么每个 view 就是一个最小的权限单位,如果一个角色拥有这个权限,那么他就可以请求这个 view 的操作。所以可以这样验证权限

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UserModel(db.Model):
    # ...
    def check(self, action):
        permission = self.permissions.filter(PermissionModel.action == action).first()
        return bool(permissions)

然后把这个权限验证写到 decorator 里去

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
permissions = list()

class Permission(object):

    def __init__(self, module=None, action=None):
        self.module = module
        self.action = action

    def check(self, module, func):
        if not self.current_user:
            return False
        return self.current_user.check('{module}.{action}'.format(
            module=module,
            action=func
        ))

    def deny(self):
        return fail(4003, u'无权访问')

    def __call__(self, func):
        permissions.append({
            'action': '{}.{}'.format(func.__module__, func.__name__),
            'name': func.__doc__
        })
        @wraps(func)
        def decorator(*args, **kwargs):
            if not self.check(func.__module__, func.__name__):
                return self.deny()
            return func(*args, **kwargs)
        return decorator

    def __enter__(self):
        if not self.check(self.module, self.action):
            try:
                self.deny()
            except Exception as e:
                raise e
            else:
                raise PermissionDeniedException

    def __exit(self):
        pass

    @property
    def current_user(self):
        return g.user

permission = Permission()

这里参考了 hustazp 的 permission

使用 func.__module__func.__name__ 结合作为权限中的 action,如果单独用 func.__name,肯定会出现相同的函数名,如果加上 func.__module__ 就在一定程度上避免了重合,并且将 func.__doc__ 来作为权限种的 name,还没想到更好的办法来自动加入 name

那么上面的用户认证换成 permission 就是下面

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@app.router('/user/info')
@permission
def user_info():
    """用户信息"""
    return render_template('user/info.html')

在开发的过程中,如果写了一个权限就要加到数据库里该有多累,于是就加了一个 permissions,这里把所有的 view 都加到这里面来,然后通过下面的脚本来加入权限

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from application.models.user import PermissionModel, RoleModel, role_permission
from application.utils.permissions import permissions
for permission in permissions:
    p = PermissionModel.query.filter_by(action=permission['action']).first()
    if not p:
        p = PermissionModel(
            name=permission['name'],
            action=permission['action']
        )
        db.session.add(p)
        db.session.commit()

role = RoleModel.query.first()  # 这里默认获取一个角色,并且赋予权限
for p in PermissionModel.query.filter_by(is_delete=False):
    r = db.session.query(role_permission).join(RoleModel).join(PermissionModel).\
        filter(
            RoleModel.id == role.id,
            RoleModel.is_delete == False,
            PermissionModel.id == p.id,
            PermissionModel.is_delete == False,
            role_permission.c.is_delete == False,
        ).first()
    if not r:
        role.permissions.append(p)

role.save()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
康耐视VIDI介绍-蓝色定位工具(Locate)
蓝色定位工具用于识别和定位图像中的特定特征或特征组。该工具的输出可用于为其他下游 ViDi 工具提供位置数据。使用该工具时您提供一个训练集,然后识别图像中的特征。您还可以使用该工具创建两种不同类型的模型。布局模型提供了检查特征是否存在以及验证区域中一个或多个特征的正确实例数的功能。可以生成节点模型,其定义一组特征之间的空间关系。
AI机器视觉
2022/06/01
3.9K0
康耐视VIDI介绍-蓝色定位工具(Locate)
康耐视深度学习VIDI介绍(1)
前几天康耐视举行了一次线上分享会,主要是对2022年他们新产品的一些介绍和老产品的更新说明。我抽时间听了一下给我的感觉是康耐视现在基本上是在all in AI,他们传统的视觉算法和平台基本上没有太大的变化,但是在AI产品这一块丰富了很多。
AI机器视觉
2022/06/01
3.3K0
康耐视深度学习VIDI介绍(1)
康耐视VIDI介绍-蓝色读取工具(Read)
蓝色读取工具用于执行光学字符识别 (OCR)。与蓝色定位工具类似,蓝色读取工具可将字符作为图像中的特征进行识别和定位。但是蓝色读取工具使用预先训练的模型为读取性能提供通用基线,无需训练。因此当工具首次配置后,它几乎可以立即识别和读取字符。工具已经知道如何读取字符,您只需要定义要在图像中的哪个位置查找字符即可。
AI机器视觉
2022/06/01
3.7K0
康耐视VIDI介绍-蓝色读取工具(Read)
18个您想了解的微小但有用的macOS功能
macOS具有许多如此小巧而有用的功能,在您偶然发现它们或有人将它们指出给您之前,很容易错过它们。
office小助手
2020/12/25
6.7K0
18个您想了解的微小但有用的macOS功能
「Adobe国际认证」Adobe Photoshop,如何裁剪并拉直照片?
裁剪是移去部分照片以打造焦点或加强构图效果的过程。在 Photoshop 中使用裁剪工具裁剪并拉直照片。裁剪工具是非破坏性的,您可以选择保留裁剪的像素以便稍后优化裁剪边界。裁剪工具还提供直观的方法,可让您在裁剪时拉直照片。
IT胶囊
2021/06/17
3.1K0
用于三维点云语义分割的标注工具和城市数据集
文章:Annotation Tool and Urban Dataset for 3D Point Cloud Semantic Segmentation
点云PCL博主
2022/04/06
2.2K0
用于三维点云语义分割的标注工具和城市数据集
独家 | 手把手教数据可视化工具Tableau
前言 数据的世界正在发生急剧变化,任何人都应该访问自己需要的数据,并具备获取任何数据的洞察力,而tableau正是帮我们洞察数据的好帮手。 Tableau作为BI tool leader ( 2016 Gartner BI chart), 它不仅是一款可视化软件,还具备不可忽略的强大的Data connection, collaboration, security management, multi-platform功能性: Data connection:Tableau Desktop可直接连接S
数据派THU
2018/01/30
19.6K0
独家 | 手把手教数据可视化工具Tableau
如何在Mac上轻松更改Finder的外观
macOS Finder是一个方便的实用程序,但是如果您自定义外观,它可能会为您提供更好的服务。这里有一些改变Finder外观的技巧!
office小助手
2020/12/24
6.6K0
如何在Mac上轻松更改Finder的外观
Parallels Toolbox for mac(pd工具箱)
专为富有创造力的个人、学生、小企业主、长期多任务处理者、IT 经理以及介于两者之间的任何人而设计。Parallels Toolbox 讓每個人都可以充分利用他們的 Mac,而不必學習複雜的系統設定。
Mac小小心
2023/04/10
6.1K0
Parallels Toolbox for mac(pd工具箱)
阿丘科技之AIDI高级应用讲解一(5)
导入混合图后,图像显示区会显示混合图每张子图,通过方向键左右切换,或者通过标注工具栏中图片id切换
AI机器视觉
2022/06/01
3.7K0
阿丘科技之AIDI高级应用讲解一(5)
FL Studio水果21最新中文版详细功能介绍
水果具有独特的底层逻辑,其开创了编曲“块”的思维。用FL Studio编曲的流程是在把一个样式编辑好,然后将编辑好的样式当做音频块,在播放列表中像“搭积木”一样任意编排,形成一首歌,这种模式非常利于电子音乐编曲。
用户7442547
2023/03/06
4.8K0
『开发技术』LabelImg安装及使用介绍
注释以PASCAL VOC格式保存为XML文件,这是ImageNet使用的格式。此外,它还支持YOLO格式
小宋是呢
2022/03/07
2.2K0
『开发技术』LabelImg安装及使用介绍
PyCharm入门教程——用户界面导览「建议收藏」
JetBrains PyCharm是一种Python IDE,其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。此外,该IDE提供了一些高级功能,以用于Django框架下的专业Web开发。
全栈程序员站长
2022/09/27
4.2K0
PyCharm入门教程——用户界面导览「建议收藏」
做机器视觉哪个软件好?
在构建机器视觉系统时,开发人员可以选择众多知名公司的商用软件包。然而,在选择这类软件时,重要的是理解这些软件提供的功能、支持的硬件以及如何轻松地配置这样的软件,以解决特定的机器视觉任务。
小白学视觉
2022/09/28
8.3K0
MATLAB GUI界面编程——一些细节问题「建议收藏」
本篇博文主要对自己在进行MATLAB GUI设计时遇到的一些细节问题进行总结,点击下面目录中的相关问题,可以直接跳转至相应位置。另外,需要声明的是,我所使用的MATLAB版本——MATLAB R2017a。
全栈程序员站长
2022/07/01
6.8K0
MATLAB GUI界面编程——一些细节问题「建议收藏」
工具 | ImagePy——UI界面支持开放插件的Python开源图像处理框架
AI 科技评论按,ImagePy 是一款 python 开源图像处理框架,其 UI 界面支持开放插件。在 github:https://github.com/Image-Py/imagepy 上,不仅有关于这款图像处理软件的详细介绍,还有一些使用示例,雷锋网 AI 科技评论接下来将详细介绍这一开源图像处理框架。
AI科技评论
2019/01/03
1.8K0
深度学习在医学影像上的应用(四)——检测
上一篇给大家介绍了深度学习在医学影像上分割的应用,这一篇我将分享深度学习在医学影像上检测应用。
医学处理分析专家
2020/06/29
3.1K0
深度学习在医学影像上的应用(四)——检测
2014版CAD操作教程(全)
l 认识AutoCAD的应用领域,让学生了解软件的专业特点及在校的优势,认识本专业在国内的发展历程及毕业后的前景。
用户7505898
2020/09/09
6.7K0
2014版CAD操作教程(全)
SAP应用界面开发-工具栏对象GUI Status与GUI Title
GUI Status与GUI Title用于自定义工具栏按钮及Report程序标题栏显示内容,可以通过SE81或直接在SE38中展开对象列表进行相关操作。如下图所示为ABAP编辑器中展开,点击:
matinal
2020/11/27
5.7K0
SAP应用界面开发-工具栏对象GUI Status与GUI Title
【MFC拓展库】上海道宁与BCGSOFT合作为您带来专业的Micrisoft Windows开发业务组件
BCGSoft Ltd.成立于1998年,是一家专门为Microsoft Windows开发业务组件的软件公司。BCGSoft旨在帮助开发人员将当今市场上先进的技术整合到他们的应用程序中。
51Component
2022/10/18
6.2K0
【MFC拓展库】上海道宁与BCGSOFT合作为您带来专业的Micrisoft Windows开发业务组件
推荐阅读
相关推荐
康耐视VIDI介绍-蓝色定位工具(Locate)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档