CRM
1. 建表
RBAC 模型: from django.db import models class Permission(models.Model): """ 权限表 """ title = models.CharField(verbose_name='标题', max_length=32) url = models.CharField(verbose_name='含正则的URL', max_length=128) def __str__(self): return self.title class Role(models.Model): """ 角色 """ title = models.CharField(verbose_name='角色名称', max_length=32) permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True) def __str__(self): return self.title class UserInfo(models.Model): """ 用户表 """ name = models.CharField(verbose_name='用户名', max_length=32) password = models.CharField(verbose_name='密码', max_length=64) email = models.CharField(verbose_name='邮箱', max_length=32) roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role', blank=True) def __str__(self): return self.name
2. 录入数据.
3.登录权限验证. permission_list
逻辑登录
from django.shortcuts import render, redirect,HttpResponse from rbac import models from django.conf import settings def login(request): "用户登录" if request.method=="GET": return render(request,"login.html") #1. 获取提交的用户名和密码 user= request.POST.get("user") print(user) pwd =request.POST.get("pwd") print(pwd) #2. 检验用户是否合法. obj =models.UserInfo.objects.filter(name =user,password=pwd).first() if not obj: return render(request,"login.html",{"msg":"用户名或者密码错误."}) #3. 获取用户信息和权限信息写入session. permission_list = obj.roles.filter(permissions__url__isnull =False).values("permissions__url").distinct() request.session["user_info"] ={"id":obj.id,"name":obj.name} request.session[settings.PERMISSION_SESSION_KEY] =list(permission_list) #queryset对象不能被序列化,需要转换成列表. return redirect("/customer/list")
settings配置
###########################权限相关########################## PERMISSION_SESSION_KEY ="permission_list"
3登录权限验证.增加Menu_list显示菜单校验 Menu_list
3.1 在登录页面的左侧加入显示菜单(查看客户与查看账单)
from django.shortcuts import render, redirect,HttpResponse from rbac import models from django.conf import settings def login(request): "用户登录" if request.method=="GET": return render(request,"login.html") #1. 获取提交的用户名和密码 user= request.POST.get("user") print(user) pwd =request.POST.get("pwd") print(pwd) #2. 检验用户是否合法. obj =models.UserInfo.objects.filter(name =user,password=pwd).first() if not obj: return render(request,"login.html",{"msg":"用户名或者密码错误."}) #3. 获取用户信息和权限信息写入session. permission_queryset = obj.roles.filter(permissions__url__isnull =False).values("permissions__url", "permissions__icon" "permissions__title" "permissions__is_menu" ).distinct() request.session["user_info"] ={"id":obj.id,"name":obj.name} menu_list=[] permission_list =[] for row in permission_queryset: permission_list.append({"permissions_url":row["permission__url"]}) if row["permission_is_menu"]: menu_list.append({"title":row["permission__title"],"icon":row["permissions__icon"],"url":row["permission__url"]}) print(menu_list) request.session[settings.PERMISSION_SESSION_KEY] =list(permission_list) #queryset对象不能被序列化,需要转换成列表. request.session[settings.PERMISSION_Menu_KEY]=menu_list return redirect("/customer/list")
3.2.为选中的菜单添加高亮功能.
3.3.权限和登录的初始化.
将用户和session的信息配置单独放置一个文件中.
新建一个init_permission文件,然后放置rbac目录下.
from django.conf import settings def init_permission(request,user): # 3. 获取用户信息和权限信息写入session. permission_queryset = user.roles.filter(permissions__url__isnull=False).values("permissions__url", "permissions__icon", "permissions__title", "permissions__is_menu", ).distinct() request.session["user_info"] = {"id": user.id, "name": user.name} menu_list = [] permission_list = [] for row in permission_queryset: permission_list.append({"permissions_url": row["permissions__url"]}) if row["permissions__is_menu"]: menu_list.append( {"title": row["permissions__title"], "icon": row["permissions__icon"], "url": row["permissions__url"]}) print("menu_list:", menu_list) print("permission_list:", permission_list) request.session[settings.PERMISSION_SESSION_KEY] = list(permission_list) # queryset对象不能被序列化,需要转换成列表. request.session[settings.PERMISSION_MENU_KEY] = menu_list
4.中间件
settings里设置
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', "web.MiddleWare.rbac.RbacMiddleware", #添加中间件. ]
View Code
逻辑
from django.utils.deprecation import MiddlewareMixin from django.conf import settings from django.shortcuts import HttpResponse,redirect,render import re class RbacMiddleware(MiddlewareMixin): """ 权限控制的中间件 """ def process_request(self,request): """ 权限控制 :param request: :return: """ #1. 获取当前请求URL current_url = request.path_info #1.5 白名单处理, for reg in settings.VALID_URL: if re.match(reg,current_url): return None #2. 获取当前session中所有的权限. permission_list = request.session.get(settings.PERMISSION_SESSION_KEY) if not permission_list: return redirect("/login") #3. 进行权限校验 print(current_url) print(permission_list) flag =False for item in permission_list: reg ="^%s$"%item.get("permissions__url") if re.match(reg,current_url): flag =True break if not flag: return HttpResponse("无权访问.")
5. 二级菜单配置
改造 models
添加Menu类
class Menu(models.Model): """ 菜单表 """ title =models.CharField(max_length=32) icon =models.CharField(max_length=32)
更改Permission类
class Permission(models.Model): """ 权限表 """ title = models.CharField(verbose_name='标题', max_length=32) url = models.CharField(verbose_name='含正则的URL', max_length=128) menu =models.ForeignKey(verbose_name="菜单",to="Menu",blank= True,null=True) def __str__(self): return self.title
生成二级菜单的数据结构: