权限粒度控制
浏览目录
简单控制
查看有没有权限,最简单的做法就是直接for循环
{% if "users/add" in permissions_list%}
例如:查看用户有没有添加用户的权限,如果有就显示添加用户按钮,没有则隐藏。
{% if "users/add" in request.actions %} <button class="btn btn-primary">添加用户</button> {% endif %}
摆脱表控制
更改数据库结构
为了方便知道用户都有哪些权限,给用户展示哪些权限,我们就需要权限组来为我们区分。
新添一张表权限组表。
# 权限表 class Permission(models.Model): title = models.CharField(max_length=32) url = models.CharField(max_length=32) action=models.CharField(max_length=32,default="") group=models.ForeignKey(to="PermissionGroup",default=1) def __str__(self): return self.title # 权限组 class PermissionGroup(models.Model): title=models.CharField(max_length=32) def __str__(self): return self.title
我们一般是先看到的是列表页面,在这个页面上是否显示添加,是否显示编辑,是否显示删除,都是需要判断的。
有无添加权限,有无删除权限,有无编辑权限,我们可以给每一个url一个代号
dict = { 1:{ 代号 /users/ list /users/add/ add /users/del(\d+)/ del /users/edit(\d+)/ edit } }
通过admin录入权限数据
class PerConfig(admin.ModelAdmin): list_display = ["title","url","action","group"] #显示字段 admin.site.register(UserInfo) admin.site.register(Role) admin.site.register(Permission,PerConfig) #绑定PerConfig类 admin.site.register(PermissionGroup)
有了权限组,可以直接按照action来查看权限。
例如:查看用户有没有添加用户的权限,如果有就显示添加用户按钮,没有则隐藏。
{% if "add" in request.actions %} <button class="btn btn-primary">添加用户</button> {% endif %}
简单类控制
通过类的实例化对象可以直接通过“.”来调用类中的方法,进行简单操作。
views.py
class Per(object): def __init__(self, actions): self.actions = actions def add(self): return "add" in self.actions def delete(self): return "delete" in self.actions def edit(self): return "edit" in self.actions def list(self): return "list" in self.actions
如果要查看登录用户对用户表都有哪些权限,可以实例化一个对象。
例如:查看用户有没有添加用户的权限,如果有就显示添加用户按钮,没有则隐藏。
{% if per.add %} <button class="btn btn-primary">添加用户</button> {% endif %}
登录验证
#查询当前登录用户的所有权限,按照url,分组id,每个权限要做的操作展示,权限列表去重 permissions = user.roles.all().values("permissions__url", "permissions__group_id", "permissions__action").distinct() print("permissions",permissions) #当前登录用户所有权限如下: '''permissions <QuerySet [{'permissions__url': '/users/', 'permissions__action': 'list', 'permissions__group_id': 1}, {'permissions__url': '/users/add', 'permissions__action': 'add', 'permissions__group_id': 1}, {'permissions__url': '/users/delete/(\\d+)', 'permissions__action': 'delete', 'permissions__group_id': 1}, {'permissions__url': '/roles/', 'permissions__action': 'list', 'permissions__group_id': 2}, {'permissions__url': '/users/edit/(\\d+)', 'permissions__action': 'edit', 'permissions__group_id': 1}]> '''
上面的数据我们使用起来并不是很方便,怎样才能得到我们想要的数据呢?我们可以以字典的形式存储他们,方便我们查询。
permission_dict={} #建立一个空字典 for item in permissions: #循环每个权限 gid=item.get("permissions__group_id") #取到组id,组作为字典的键 if not gid in permission_dict: #如果没有组作为键,新建键名再添加数据 permission_dict[gid]={ "urls":[item["permissions__url"],], "actions":[item["permissions__action"],], } else: #有键则直接添加数据 permission_dict[gid]["urls"].append(item["permissions__url"]) permission_dict[gid]["actions"].append(item["permissions__action"]) print(permission_dict) #在session中注册权限字典,方便后面查询 request.session["permission_dict"]=permission_dict
就会得到以下的数据:
'''{{'1': {'urls': ['/users/', '/users/add', '/users/delete/(\\d+)', '/users/edit/(\\d+)'], 'actions': ['list', 'add', 'delete', 'edit']}, '2': {'urls': ['/roles/'], 'actions': ['list']}} '''
中间件检验权限
有了注册在session中的permission_dict字典,我们就可以很方便的查询每个用户所拥有的权限。
'''权限校验二''' permission_dict=request.session.get("permission_dict") #将权限字典在session中注册 print(permission_dict) for item in permission_dict.values(): #按组循环 urls=item["urls"] #urls为每个组中的所有url for rule in urls: #遍历所有url rule="^%s$"%rule # 字符串拼接重新定义权限 ret=re.match(rule,current_path) #按规则匹配当前路径 if ret: #匹配成功 print("actions",item["actions"]) request.actions=item["actions"] #给对象设置属性,后面调用request.actions就能拿到当前用户对当前表所有权限 return None return HttpResponse("不好意思,您没有访问权限!")