RBCA权限管理笔记(模型设计)

Django RBCA权限管理实现详解
本文详细介绍了基于角色的权限管理(RBCA)在Django中的实现,包括概念解释、权限模型设计、代码解析及具体实现。通过创建用户、角色、URL、操作等表,并建立关联,实现对用户URL操作的精细控制。文中还强调了Python ORM的数据库链表操作和跨表查询技巧。
部署运行你感兴趣的模型镜像

Django-RBCA权限管理实现笔记(一)

概念解释:

RBCA:全称基于角色的权限管理,个人理解:每个用户会有多种角色,每个角色会有多种权限,我们需要实现每个用户的权限控制,那么就要通过角色,来进行关联。
每个权限对应的其实就是一个url,控制权限就是控制用户是否可以对这个url是否能够操作,再具体就是对这个url如何操作(增删改查)。

权限模型设计 models.py

一共七张表,可以实现对每个用户的操作URL的增删改查的具体控制;

from django.db import models


# 用户表
class User(models.Model):
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)

    class Meta:
        verbose_name_plural = "用户表"

    def __str__(self):
        return self.username


# 角色表
class Role(models.Model):
    caption = models.CharField(max_length=32)

    class Meta:
        verbose_name_plural = "角色表"

    def __str__(self):
        return self.caption


# 用户角色关系表
class User2Role(models.Model):
    # 一个用户拥有多个权限,一个权限也可以给多个用户
    u = models.ForeignKey(User, on_delete=models.CASCADE)
    r = models.ForeignKey(Role, on_delete=models.CASCADE)

    class Meta:
        verbose_name_plural = "用户分配角色"
    
    def __str__(self):
        return "%s - %s" % (self.u, self.r)


# 增删改查详细权限表  操作表
class Action(models.Model):
    # 用户对某个url的增删改查的权限
    #  get  post  del put
    caption = models.CharField(max_length=32)
    code = models.CharField(max_length=32)

    class Meta:
        verbose_name_plural = "操作表"

    def __str__(self):
        return self.caption


# 菜单表
class Menu(models.Model):
    caption = models.CharField(max_length=32)
    parent = models.ForeignKey('self', related_name='p', blank=True, null=True, on_delete=models.CASCADE)

    def __str__(self):
        return '%s' % self.caption


# URL
class Permission(models.Model):
    # 所有的URL
    caption = models.CharField(max_length=32) 
    url =models.CharField(max_length=32)
    menu = models.ForeignKey(Menu, null=True, blank=True, on_delete=models.CASCADE)

    class Meta:
        verbose_name_plural = "URL表"
    def __str__(self):
        return '%s - %s' % (self.caption, self.url)


# 权限表
class Permission2Action(models.Model):
    # 角色对某个url的具体操作权限
    # 将url和增删改查关联起来
    p = models.ForeignKey(Permission, on_delete=models.CASCADE)
    a = models.ForeignKey(Action, on_delete=models.CASCADE)

    class Meta:
        verbose_name_plural = "权限表"
    def __str__(self):
        return '%s - %s: %s?t=%s' % (self.p.caption, self.a.caption, self.p.url, self.a.code, )


# 角色具体可以操作的url的权限和角色进行绑定
class Permission2Action2Role(models.Model):
    p2a = models.ForeignKey(Permission2Action, on_delete=models.CASCADE)
    r = models.ForeignKey(Role, on_delete=models.CASCADE)

    class Meta:
        verbose_name_plural = "角色分配权限"
    def __str__(self):
        return '%s ==> %s' % (self.r, self.p2a)


代码解析:
  1. 第一步:创建用户表以及角色表,多对多关系进行绑定:实现用户分配角色(用户角色关系表);

  2. 第二步:创建URL表以及操作表,多对多关系进行绑定:实现对URL具体操作的实现(权限表);

  3. 第三步:将角色表和权限表进行关联,实现角色分配权限(Permission2Action2Role)

4.第四步: 创建菜单表,并且进行自关联(自己调用自己),可以实现菜单动态生成,允许不调用,不调用就是根菜单

5.第五步:将URL表中的每个url挂靠到菜单表中,实现url与菜单的关联;

具体实现: Views.py
from django.shortcuts import HttpResponse
from . import models


def login_test(request):
    # 步骤一: 获取用户名
    # 1.通过用户名获取该用户的所有角色
    username = request.GET.get('u')  # 获取用户名
    # user_obj = models.User.objects.get(username=username)   # 根据用户名获取用户数据

    # 方式1.根据用户数据获取用户所有角色
    # user2_role_list = models.User2Role.objects.filter(u_id=user_obj.id)
    # print(user2_role_list)

    # 步骤二 通过用户名获取所有角色列表
    # 方式2.跨表操作: 跨两张表直接根据获取的用户名获取到该用户名下的所有角色  获取到角色列表
    # <QuerySet [<Role: CEO>, <Role: 搬砖者>, <Role: 部门经理>]>
    role_list = models.Role.objects.filter(user2role__u__username=username)

    # p = models.Permission2Action2Role.objects.filter(r__in=role_list)  # Permission2Action2Role对象

    # 用户登录获取的两个值:第一个所有权限在 session 中放置
    # 步骤三 根据角色列表,获取到用户所有的去重后的权限,放置在session中;
    # 我们可以通过表关联以及反向关联,直接换获取到当前用户对应角色的所有的权限
    # 通过该用户的角色列表,间接获取到该用户对应角色的所有权限
    permission2action = models.Permission2Action.objects.\
        filter(permission2action2role__r__in=role_list).\
        values('p__url', 'a__code').distinct()

    for item in permission2action:
        print(item)

    # 用户登录获取的两个值:第二个 在菜单中显示的权限, 去重然后再筛查 exclude(p__menu__isnull=True)
    # 获取用户应该在页面菜单栏显示的 权限  -- 如果菜单能够下拉,那么必须在最后一层跳转层
    menu_leaf_list = models.Permission2Action.objects. \
        filter(permission2action2role__r__in=role_list). \
        values('p__url', 'p__caption', 'p__menu').distinct().exclude(p__menu__isnull=True)

    return HttpResponse('....')


代码解析:

代码目的:\

  1. 获取登录用户的所有权限,并且去重;
  2. 获取需要在菜单中显示的权限

关系:用户名 --> 用户id --> 用户角色 --> 角色分配权限表 链表操作获取到所有分配的权限

重点:
  1. python ORM的数据库链表操作,跨表查询;
  2. __in : 关键字的值是否在集合中,不用再去循环;
  3. distinct() : 去重操作;

这是第一步的笔记。强化一下认知。!
一个坚持自学的小白,如果有志同道合,也在自学的朋友,我们可以一起交流!没有任何商业目的,只是想一起学习!
一个坚持自学的小白,如果有志同道合,也在自学的朋友,我们可以一起交流!没有任何商业目的,只是想一起学习!

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值