上一篇博客我们记录了一下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我们就介绍到这里了,谢谢大家关注!

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

  1. Django的Rbac介绍1

    1.django的权限管理叫做RBAC 我们在百度上查看RBAC的概念如下 基于角色的权限访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的 ...

  2. Django的Rbac介绍3

    今天的博客主要是记录一下如何实现左侧菜单,这里我们想实现的效果就是,如果用户有查看用户的权限,则显示查看用户的左侧菜单,如果用户有查看角色的权限,则显示查看角色的左侧菜单,如果两者都有,则需要显示两个 ...

  3. Django - Django框架 简单介绍

    Django框架 简单介绍 本文地址: http://blog.csdn.net/caroline_wendy/article/details/29172271 1. 介绍 Django是一个开放源码 ...

  4. Django项目结构介绍

    官网下载网址:https://www.djangoproject.com/download/ 安装(安装最新LTS版): pip3 install django==2.0.7 创建一个django项目 ...

  5. Django中ORM介绍和字段及字段参数 Object Relational Mapping(ORM)

    Django中ORM介绍和字段及字段参数   Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简 ...

  6. RBAC 介绍 (权限)

    RBAC是什么? RBAC是基于角色的访问控制(Role-Based Access Control )在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限.这就极大地简化了权 ...

  7. Openresty最佳案例 | 第8篇:RBAC介绍、sql和redis模块工具类

    转载请标明出处: http://blog.csdn.net/forezp/article/details/78616738 本文出自方志朋的博客 RBAC介绍 RBAC(Role-Based Acce ...

  8. 6月20日 Django中ORM介绍和字段、字段参数、相关操作

    一.Django中ORM介绍和字段及字段参数 二.Django ORM 常用字段和参数 三.Django ORM执行原生SQL.在Python脚本中调用Django环境.Django终端打印SQL语句 ...

  9. rbac介绍、自动生成接口文档、jwt介绍与快速签发认证、jwt定制返回格式

    今日内容概要 RBAC 自动生成接口文档 jwt介绍与快速使用 jwt定制返回格式 jwt源码分析 内容详细 1.RBAC(重要) # RBAC 是基于角色的访问控制(Role-Based Acces ...

随机推荐

  1. 学习别人的rpc框架

    https://my.oschina.net/huangyong/blog/361751 https://gitee.com/huangyong/rpc 在此文基础上的另一个实现,解决了原文中一些问题 ...

  2. dockerfile构建nginx并结合php

    转自:https://www.cnblogs.com/jsonhc/p/7799358.html 查看nginx和php的目录结构: [root@docker docker_demo]# tree n ...

  3. 经典论文翻译导读之《Finding a needle in Haystack: Facebook’s photo storage》

    https://github.com/chrislusf/seaweedfs [译者预读]面对海量小文件的存储和检索,Google发表了GFS,淘宝开源了TFS,而Facebook又是如何应对千亿级别 ...

  4. 支持向量机通俗导论(理解SVM的三层境界)(ZT)

    支持向量机通俗导论(理解SVM的三层境界) 原文:http://blog.csdn.net/v_JULY_v/article/details/7624837 作者:July .致谢:pluskid.白 ...

  5. java字符串格式化:String.format()方法的使用

    转自:http://kgd1120.iteye.com/blog/1293633 常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的读者应 ...

  6. 正则表达式(TypeScript, JavaScript)

    课题 使用正则表达式匹配字符串 使用正则表达式 "\d{3}-(\d{4})-\d{2}" 匹配字符串 "123-4567-89" 返回匹配结果:'" ...

  7. Python基本模块介绍:sys、platform

    sys模块 常用函数 sys.argv 命令行参数,实现从程序外部向程序传递参数. sys.path 模块搜索路径. sys.platform 获取当前系统平台. sys.version 获取pyth ...

  8. webservice调用dll

    今天客户那里报出来,ws通讯不成功.但是在本机和windows2003上都可以测试成功.WS的页面(asmx)可以出来,但是点击接口方法,调用就报http500错误.   网站无法显示该页面  HTT ...

  9. RPM安装命令总结

    RPM安装命令总结 在 Linux 操作系统下,几乎所有的软件均通过RPM 进行安装.卸载及管理等操作.RPM 的全称为Redhat Package Manager ,是由Redhat 公司提出的,用 ...

  10. oracle创建数据库步骤

    1.oracle安装成功后, cmd sqlplus,然后system/orcl as sysdba 2.更改scott的密码,scott的默认密码是tiger SQL> alter user ...