什么是权限:django
谁对什么资源能作什么操做。session
管理权限的实现有不少,这里实现一个最简单的管理权限的实现方式:rbac ( role based access control )app
实现的一个基本思路:url
一张user用户表,一张role角色表,一张permission权限表spa
其中,用户与角色是多对多的关系,角色和权限是多对多的关系设计
用户登陆后,经过用户能够获取当前登陆人的全部权限,并设置session值(request.session["permission_list"] = 值)code
而后设置中间件,在用户登陆时,设置一个白名单,若是用户没有登陆就去登陆,若是登陆就直接从session中取出session_list权限列表,正则匹配这个权限列表,若是匹配上,返回None,不然,返回响应没有访问权限。而且用户能够在左侧菜单查看本身的访问权限有哪些。中间件
首先第一步:表单的设计blog
若是user用户表借助了auth模块,就直接import 这张表继承
在rbac这个APP中:(将管理权限设为一个独立的app(组件)) models.py
from django.db import models # Create your models here. class User(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) roles=models.ManyToManyField("Role") def __str__(self): return self.name class Role(models.Model): title=models.CharField(max_length=32) permissions=models.ManyToManyField("Permission") def __str__(self): return self.title class Permission(models.Model): title = models.CharField(max_length=32) url = models.CharField(max_length=32) code=models.CharField(max_length=32,default="list") def __str__(self): return self.title
因为是基于Xadmin的,因此咱们要借助这个后台管理,因此要将这几张模型表注册
在rbac app下的Xadmin.py中注册:
from Xadmin.service.Xadmin import site,ModelXadmin from .models import User from .models import Role from .models import Permission site.register(User) site.register(Role) class PermisssionConfig(ModelXadmin): list_display = ["id","title","url","code"] site.register(Permission,PermisssionConfig)
设置中间件,而且将权限列表保存在session中
在rbac下建立一个service的package,而后在新建一个.py文件,用于放置中间件的逻辑。
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 white_list=["/login/","/reg/","/index/","/admin/*"] for ignore_url in white_list: ret=re.search(ignore_url,current_path) if ret: return None # 校验是否登陆 user_id=request.session.get("user_id") if not user_id: return redirect("/login/") # 校验是否拥有相应权限 permission_list=request.session.get("permission_list") print("permission_list",permission_list) for permission in permission_list: permission="^%s$"%permission ret=re.search(permission,current_path) if ret: return None return HttpResponse("没有访问权限!")
登陆成功后,校验经过后,执行取值和给session赋值:(将这个过程封装到一个.py文件中,哪儿须要直接import便可)
def init_session_permission(user,request): permissions = user.roles.all().values("permissions__url","permissions__code","permissions__title").distinct() print("permissions",permissions) permission_list = [] menu_permission_dict={} for permission in permissions: permission_list.append(permission.get("permissions__url")) if permission.get("permissions__code")=="list": menu_permission_dict[permission.get("permissions__title")]=permission.get("permissions__url") request.session["permission_list"] = permission_list request.session["menu_permission_dict"] = menu_permission_dict
备注:要对筛选的结果进行去重操做。由于一个用户会有多个role。
在用户左侧菜单展现可访问的页面
左侧展现页面:首先一点,咱们能够给用户展现权限中的那些url,增删改查中,改删是有动态参数的,没法展现,而添加页面显得有些多余,因此咱们能够将全部的权限路径中属于展现的url过滤出来,而后加入左侧菜单栏中,为了方便快捷,咱们能够在这个permission权限表中,增长一个字段,叫code,咱们能够将增删改查设置为四类,而后在登陆成功,设置session值时,对查这个url进行过滤,单独保存在一个session中,而后咱们能够在相应页面中直接取值,便可,大大的方便了展现信息的代码冗余和可复用性。具体的HTML页面中,咱们能够设置到一个母版中,而后用户就能够在不一样的页面直接经过继承就能够实现左侧菜单栏的效果。
具体的HTML的实现:
<div class="menu"> <div class="panel panel-danger"> <div class="panel-heading">Panel heading without title</div> <div class="panel-body"> {% for title,url in request.session.menu_permission_dict.items %} <p><a href="{{ url }}">{{ title }}</a></p> {% endfor %} </div> </div> </div>