Django的Rbac的介绍2

上一篇博客我们记录了一下Django中使用Rbac,但是上一篇博客中的方法有一点不好,就是,因为我要在html文件中控制:如果用户有某个权限,则显示这个权限所代表的按钮,但是我现在只有1张表的增删改查,但是如果我有多张表呢,我难道要每张表都写一次类似下面的代码吗?

                     {%  if "/user/del/(\d+)" in per_list %}
                        <a href="/user/del/{{ user.id }}"><button type="button" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span>&nbsp删除</button></a>
                     {% endif %}

  

这样就必须麻烦了,因为上面是user表,如果我还有一张role的表,我是不是也要在写一遍呢?

                     {%  if "/roles/del/(\d+)" in per_list %}
                        <a href="/user/del/{{ user.id }}"><button type="button" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span>&nbsp删除</button></a>
                     {% endif %}

  

可能有的同学会说:我当然要每张表写一次了,但是大家是否可以想一想,不论是roles表还是user表,或者是其他的表,他们的权限是不是都是一样的,永远都逃不出增删改查4个权限,那么我们就可以从这里入手来进行优化

针对上面的问题,我们可以下面的方式解决

1、首先我们需要重新设计数据库

用户表如下,这张表我们没有做任何改动,和方法1是一样的

class Userinfo(models.Model):
    username = models.CharField(max_length=64)
    uerpwd = models.CharField(max_length=64)
    roles = models.ManyToManyField(to="Role")

    def __str__(self):
        return self.username
    class Meta:
        verbose_name = "用户表"
        verbose_name_plural = verbose_name

  

角色表如下,这张表我们没有做任何改动,和方法1是一样的

class Role(models.Model):
    title = models.CharField(max_length=64)
    pers = models.ManyToManyField(to="per")

    def __str__(self):
        return self.title
    class Meta:
        verbose_name="角色表"
        verbose_name_plural = verbose_name

  

下面的表,我们就和方法1不一样的了

首先我们看下权限表

class per(models.Model):
    title = models.CharField(max_length=64)
    url = models.CharField(max_length=128)
    action = models.CharField(max_length=32, default="")
    group = models.ForeignKey("PerGroup", default=1)
    def __str__(self):
        return self.title
    class Meta:
        verbose_name = "权限表"
        verbose_name_plural = verbose_name

  

权限表我们增加了2个字段

action字段描述的就是四种操作,增删改查,比如list就是查,del就删,edit就是改,add就是增加

group字段描述的就是我这个权限属于哪张表,比如属于用户表,或者权限表

所有我们这里还需要增加一张表

class PerGroup(models.Model):
    title = models.CharField(max_length=32)

    def __str__(self): return self.title

    class Meta:
        verbose_name = "权限组"
        verbose_name_plural = verbose_name

  

2、下面我们看下在登陆的视图函数中是如何处理权限的,到底把哪些信息放到session中了

 # 2、方案2,是我们重新设计数据库后的方法
            obj  = userobj.roles.all().values("pers__url","pers__group_id","pers__action")

            print(obj)
            # print(dir(request.session))
            # print("=" * 120)
            # return redirect("/user/")

            # 构建一个这样的数据结构
            per_dict = {}
            for item in obj:

                gid = item.get("pers__group_id")
                if gid in per_dict.keys():
                    per_dict[gid]["urls"].append(item["pers__url"])
                    per_dict[gid]["action"].append(item["pers__action"])
                else:
                    per_dict[gid] = {
                        "urls":[item["pers__url"],],
                        "action" :[item["pers__action"],]
                    }
            request.session["per_dict"] = per_dict

            return HttpResponse("登陆成功")
        else:
            return render(request, "rbac_login.html")

  

我们实际构建了一个这样的字典,然后把这个字典放到session中

{

“group_id1”:{

  action:[aa,bb,cc],

  urls:[aa,bb,cc],

}

"group_id2":{

  action:[aa,bb,cc],

  urls:[aa,bb,cc]

}

}

3、然后我们看下中间件函数是如何处理的

        per_dict = request.session.get("per_dict")
        print(per_dict)
        for item in per_dict.values():
            urls = item["urls"]
            for reg in urls:
                reg = "^" + reg + "$"

                ret = re.match(reg,current_path)
                if ret:
                    print("action",item["action"])

                    # 为request对象赋值一个新的变量
                    request.actions =  item["action"]

                    return None
        return HttpResponse("无权限访问")

这里还有一个知识点,我们为request这个对象赋值了一个变量,那么以后所有request这个对象都可以去获取action这个变量的值

其实这里和方法1是没有区别的,都是从session中取出urls的信息,然后和当前的url进行对比,如果能匹配上,则通过。如果匹配不上,则返回无权限

4、重点是在这里,主要是在html中处理就会简单一些

我们先看下视图函数是如何渲染html页面的

def user(request):
    userobj = rbacmodels.Userinfo.objects.all()

    # 方案1的代码处理逻辑
    # per_list = request.session.get("per_list")
    # print(per_list)
    # return render(request,"rbac_user.html",{"user_list":userobj,"per_list":per_list})

    # 方案2的代码处理逻辑
    uid = request.session.get("userid")
    # user = rbacmodels.Userinfo.objects.filter(id=uid).first()

    action = request.actions

    user_list = rbacmodels.Userinfo.objects.all()

    return render(request,"rbac_user.html",{"action":action,"user_list":user_list})

  

首先从request对象中获取我们在中间件函数中赋值的actions变量,然后渲染到前端

我们在看下前端的html页面,我们只需要判断这次的用户对某张表是否有del、list、edit、add权限就可以了,因为这些信息我们都单独放在action中了

{#                 方式1#}
                     {%  if "/user/del/(\d+)" in per_list %}
                        <a href="/user/del/{{ user.id }}"><button type="button" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span>&nbsp删除</button></a>
                     {% endif %}
{#                    方式2#}
                     {%  if "del" in request.actions %}
                        <a href="/user/del/{{ user.id }}"><button type="button" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span>&nbsp删除</button></a>
                     {% endif %}

  

这里我们可以对比一下方式1和方式2的区别

只需要判断是否有增删改查的权限就可以了,无需在判断表的名称

至此Djang的权限控制我们就做完了

----------------------------------------------------------------------------------------------------------------------------

我们还有一个点可以优化一下,我们可以重新写一个类,这个类我们需要传递一个action进来,然后定义增删改查4个方法,每个方法都判断action中是否有对应的方法就可以了

class Per(object):
    def __init__(self,actions):
        self.actions = actions
    def add(self):
        return "add" in self.actions
    def edit(self):
        return "edit" in self.actions
    def dele(self):
        return "del" in self.actions
    def list(self):
        return "list" in self.actions

  

所以我们在前端判断就更加简单了

先在视图函数中实例化一个对象

    Per_obj = Per(request.actions)

    return render(request,"rbac_user.html",{"Per_obj":Per_obj})

  

然后在htmlz中调用这个实例变量的方法就可以了

是不是这样写就更加简单了

好了Django的Rbac我们就介绍到这里了,谢谢大家关注!

 

原文地址:https://www.cnblogs.com/bainianminguo/p/10015400.html

时间: 2024-10-23 07:32:23

Django的Rbac的介绍2的相关文章

django的RBAC介绍1

1.django的权限管理叫做RBAC 我们在百度上查看RBAC的概念如下 基于角色的权限访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注.在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权限的管理.在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色.角色可依新的需求和系统的合并而赋予新的

Django默认权限机制介绍及实践

演示Django版本为当前最新版本v2.2 当Django配置文件中的INSTALL_APPS包含了django.contrib.auth时,就默认启用了一个简单的权限系统,提供了为用户或组分配权限的方法 之所以说简单呢?主要是因为: 默认的权限系统是基于表的控制,权限最小粒度是表 也就是说,假如有一个Blog表,我们可以赋予用户或组对Blog表有delete的权限,那么用户或组成员就可以删除全部Blog,是不能控制用户只能删除自己创建的blog的 如果希望用户只能删除自己创建的Blog,不能删

Celery在Django中的使用介绍

Celery在Django中的使用介绍 Celery简介 celery是一个简单.灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必须工具. 它是一个专注于实时处理的任务队列,同时也支持任务调度. 何为任务队列 任务队列:是一种在线程和机器间分发任务的机制. celery的三大组成部分 worker 任务执行单元-->Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中. broker(存tasks的仓库) 消息中间件--> Celery

用Django做一个团队介绍

所用工具 Pychrm 社区版 Django 2.x Python 3.6.4 总目录 settings中的设置 总的路由设置 templates中的index.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>团队介绍</title> <style type="text/cs

Django框架学习-01Django介绍

01-Django介绍 02-HTTP协议介绍 01-Django介绍 1.什么是Web框架? 随着Web最新发展趋势的不断升级,Web项目开发也越来越难,而且需要花费更多的开发时间.所以,Web程序员灵活运用Web开发框架显得更为重要. Web框架(Web framework)或者叫做Web应用框架(Web application framework),是用于进行Web开发的一套软件架构.大多数的Web框架提供了一套开发和部署网站的方式.为Web的行为提供了一套支持支持的方法.使用Web框架,

基于Django实现RBAC权限管理

概述 RBAC(Role-Based Access Control,基于角色的访问控制),通过角色绑定权限,然后给用户划分角色.在web应用中,可以将权限理解为url,一个权限对应一个url. 在实际应用中,url是依附在菜单下的,比如一个简单的生产企业管理系统,菜单可以大致分为以下几块:制造.资材.生产管理.人事.财务等等.每个菜单下又可以有子菜单,但最终都会指向一个url,点击这个url,通过Django路由系统执行一个视图函数,来完成某种操作.这里,制造部的员工登录系统后,肯定不能点击财务

django简介,安装,文件介绍,三板斧(render,HttpResponse,redirect)HTTP协议,用socket实现简单版web框架,用wsgiref,jinja2,pymysql实现Django运行流程

1.web应用(https://www.cnblogs.com/Dominic-Ji/p/9167438.html) c/s,b/s架构c/s:客户端 服务端b/s:浏览器 服务器?   2.HTTP协议: 超文本传输协议 四大特性: 1.基于TCP/IP作用在应用层之上的协议,底层实现仍为socket 2.基于请求响应:通信一定是从客户端开始,服务器端接收到客户端一定会做出对应响应 3.无状态:协议不对任何一次通信状态和任何数据做保存 4.无连接:一次连接只完成一次请求-响应,请求-响应完毕后

django的RBAC认证z;自定义auth_user表;认证组件权限组件源码分析;认证组件;权限组件

一 RBAC 1.RBAC:全称(Role-Based Access Control):指的是基于用户权限访问控制的认证. 2.Django框架采用的是RBAC认证规则,RBAC认证规则通常会分为:三表规则,五表规则:Django采用的是六表规则. # 三表:用户表.角色表.权限表# 五表:用户表.角色表.权限表.用户角色关系表.角色权限关系表# 六表:用户表.角色表.权限表.用户角色关系表.角色权限关系表.用户权限关系表 3.在Django中六表之间是都是多对多的关系,可通过下面字段跨表访问

Django的用户认证----介绍

Django自带了一个用户认证系统.它处理用户账户.组.权限和基于cookie的用户会话. 概括 Django认证系统处理认证和授权.简单的说,认证是验证一个用户被声明为谁,授权是确定一个认证的用户允许做什么. 认证系统由下面的组成: 用户 权限:二进制标志,标明用户是否可以执行指定的任务 组:应用标签和权限给多个用户的通用方法 可配置的密码hash系统 用户登录的表单和视图工具或者限制的内容 可插入模块的后端系统 Django的认证系统只提供简单的方法,并不提供在web认证系统找到的一些特性.