权限粒度控制

浏览目录

 

简单控制

查看有没有权限,最简单的做法就是直接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("不好意思,您没有访问权限!")

  

posted @ 2018-05-06 18:33  高~雅  阅读(1226)  评论(1编辑  收藏  举报