Xadmin权限管理

需求分析:
1.判断用户是否登陆,未登陆就不能进入其他页面
2.为用户分配不同的权限,用户的操作只能在权限范围之内
3.将用户可操作的权限显示在页面山,点击能进入该页面操作

  模型表的建立   

1.对每个用户建立角色,每个角色有着不同的权限
2.权限的字段要设有相应的权限操作路径和操作名称
3.用户可有多个角色,每个角色可有多个用户。用户和角色:ManyToMany
4.每个角色可有多个权限,同一个权限也可被多个用户使用 角色和权限:ManyToMany
from django.db import models
# Create your models here.
class UseInfo(models.Model):
    username=models.CharField(max_length=25,verbose_name='用户名')
    passwd=models.CharField(max_length=25,verbose_name='密码')
    roles=models.ManyToManyField(to="Role",verbose_name='角色')
    def __str__(self):
        return self.username
class Role(models.Model):
    title=models.CharField(max_length=32,verbose_name='角色')
    permissions=models.ManyToManyField(to="Permission",verbose_name='权限')
    def __str__(self):
        return self.title
class Permission(models.Model):
    title=models.CharField(max_length=32,verbose_name="权限")
    url=models.CharField(max_length=255,verbose_name="执行路径")
    code=models.CharField(max_length=32,verbose_name='权限代号')
    def __str__(self):
        return self.title

  2.用户登陆后,设置session  

用户登陆之后,将用户id和权限注册到session中
if user:
    # 向session注入user信息
    request.session["user_id"] = user.pk
    # 向session注入当前登录人的权限列表
    from Rbac.service.rbac import init_permission
    init_permission(user,request)
    return redirect("/index/")

用建个py文件注册用户权限

def init_permission(user,request):
    ##多对多的关系,因此使用all
    permissions=user.roles.all().values("permissions__url","permissions__title","permissions__code")
    #print(permissions)
    #< QuerySet[{'permissions__url': '/Xadmin/Rbac/useinfo/', 'permissions__title': '查看用户', 'permissions__code': 'list'}
    permission_list=[]
    for perm in permissions:
        permission_list.append(perm.get("permissions__url"))
    #将权限注册到session中
    request.session["permission_list"] = permission_list

  3.设置中间件  

对用户的请求做出判断,判断出该用户当前请求是否符合要求,对于用户的每次请求,设置中间件来判断
1.登陆,主页,这些路径不设置验证,让所有用户都可访问
white_url=["/login/","/index/"]
        if current_path in white_url:
            return None
2.进入查看,修改页面时,判断是否有这些权限
['/Xadmin/Rbac/useinfo/', '/Xadmin/Rbac/useinfo/add/', '/Xadmin/Rbac/useinfo/change/(\\d+)/', '/Xadmin/Rbac/useinfo/del/(\\d+)/']
  permission_list=request.session.get("permission_list")
        print("他是:",permission_list)
        if  current_path not in permission_list:
            return HttpResponse("没有权限")

但是在点击编辑和删除时,却显示没有权限,原因?
点编辑和删除时由于有参数,回显示具体的值,/Xadmin/Rbac/useinfo/change/1/,而permission_list中给却是'/Xadmin/Rbac/useinfo/change/(\\d+)/'
因此匹配不上,显示无权限。应该用正则匹配完成
permission_list=request.session.get("permission_list")
for permission in permission_list:
    ret=re.search(permission,current_path)
    if ret:return None
return HttpResponse("没有权限")
此时更换用户,此用户只有查看权限:
['/Xadmin/Rbac/useinfo/', '/Xadmin/Rbac/role/']
在访问/Xadmin/Rbac/role/add/时,却能访问成功,原因?
在匹配时,匹配的规则是/Xadmin/Rbac/role/,匹配对象/Xadmin/Rbac/role/add/,
匹配的结果为/Xadmin/Rbac/role/,ret为真,会通过验证

因此要限制匹配对象开始值和结束值
for permission in permission_list:
        permission="^%s$"%permission
        ret=re.search(permission,current_path)
        if ret:return None
    return HttpResponse("没有权限")

3.设置admin

 

让所有用户都能进入admin,因此将admin设置到白名单中,此时若仍用下面这种该方法,会出问题
white_url=["/login/","/index/","/admin/"]
if current_path in white_url:
return None
进入admin后,会发现地址栏出现变化:/admin/login/?next=/admin/
此时在用in,则当前地址匹配不到admin,因此在匹配时,让用正则进行匹配
white_url=["/login/","/index/","/admin/*"]
        for url in white_url:
            url="^%s"%url
            ret=re.search(url,current_path)
            if ret:return None
由于admin有参数,此时不能加$
设置中间件
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse,render
import re
class ValidPermission( MiddlewareMixin):
    def process_request(self,request):
        ##查看当前路径
        #print("path",request.path)
        current_path=request.path
        #登陆,主页,admin这些路径不设置验证,让所有用户都可访问
        white_url=["/login/","/index/","/admin/*"]
        for url in white_url:
            url="^%s"%url
            ret=re.search(url,current_path)
            if ret:return None
        ##判断是否登陆
        is_login=request.session.get("user_id")
        if not is_login:
            return redirect("/login/")
        ##进入查看,修改页面时,判断是否有这些权限##
        permission_list=request.session.get("permission_list")
        print("他是:",permission_list)
        for permission in permission_list:
            permission="^%s$"%permission
            ret=re.search(permission,current_path)
            if ret:return None
        return HttpResponse("没有权限")
View Code

4.页面左侧显示该用户的权限

显示的权限名是个a标签,当点击时,执行该操作,因此,编辑和删除权限不能显示出来。
在向session中注册时,将添加和查看的url和对应的操作名也注册进去,但是谮言给判断当前url时哪种操作?
可以为权限表新添个code字段,来描述url,如增加操作,就将code设置为add,显示操作,设置为list,通过判断code字段进行添加
def init_permission(user,request):
    ##多对多的关系,因此使用all
    permissions=user.roles.all().values("permissions__url","permissions__title","permissions__code")
    #print(permissions)
    #< QuerySet[{'permissions__url': '/Xadmin/Rbac/useinfo/', 'permissions__title': '查看用户', 'permissions__code': 'list'}
    permission_list=[]
    menu_permission={}
    for perm in permissions:
        permission_list.append(perm.get("permissions__url"))
        if perm.get("permissions__code")=="list" or perm.get("permissions__code")=="add":
            menu_permission[ perm.get("permissions__title")]=perm.get("permissions__url")
    #将权限注册到session中
    request.session["permission_list"] = permission_list
    request.session["menu_permission"]= menu_permission
在页面上将权限菜单显示在左边,应将其固定,即页面往下拉时,该菜单仍在这个位置,要用到 position: fixed这个属性,
对于文本内容用到overflow: auto和 position: fixed
 
 

 

 
 
 

 

 
 

 

 
 
 
posted @ 2018-06-13 21:53  JERD  阅读(4174)  评论(0编辑  收藏  举报