模型设计
from django.db import models
# 用户表
class User(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
class Meta:
verbose_name_plural = "用户表"
def __str__(self):
return self.username
# 角色表
class Role(models.Model):
caption = models.CharField(max_length=32)
class Meta:
verbose_name_plural = "角色表"
def __str__(self):
return self.caption
# 用户角色关系表
class User2Role(models.Model):
# 一个用户拥有多个权限,一个权限也可以给多个用户
u = models.ForeignKey(User, on_delete=models.CASCADE)
r = models.ForeignKey(Role, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "用户分配角色"
def __str__(self):
return "%s - %s" % (self.u, self.r)
# 增删改查详细权限表 操作表
class Action(models.Model):
# 用户对某个url的增删改查的权限
# get post del put
caption = models.CharField(max_length=32)
code = models.CharField(max_length=32)
class Meta:
verbose_name_plural = "操作表"
def __str__(self):
return self.caption
# 菜单表
class Menu(models.Model):
caption = models.CharField(max_length=32)
parent = models.ForeignKey('self', related_name='p', blank=True, null=True, on_delete=models.CASCADE)
def __str__(self):
return '%s' % self.caption
# URL
class Permission(models.Model):
# 所有的URL
caption = models.CharField(max_length=32)
url =models.CharField(max_length=32)
menu = models.ForeignKey(Menu, null=True, blank=True, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "URL表"
def __str__(self):
return '%s - %s' % (self.caption, self.url)
# 权限表
class Permission2Action(models.Model):
# 角色对某个url的具体操作权限
# 将url和增删改查关联起来
p = models.ForeignKey(Permission, on_delete=models.CASCADE)
a = models.ForeignKey(Action, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "权限表"
def __str__(self):
return '%s - %s: %s?t=%s' % (self.p.caption, self.a.caption, self.p.url, self.a.code, )
# 角色具体可以操作的url的权限和角色进行绑定
class Permission2Action2Role(models.Model):
p2a = models.ForeignKey(Permission2Action, on_delete=models.CASCADE)
r = models.ForeignKey(Role, on_delete=models.CASCADE)
class Meta:
verbose_name_plural = "角色分配权限"
def __str__(self):
return '%s ==> %s' % (self.r, self.p2a)
封装RBCA用户权限模块以及装饰器
为了方便权限认证的调用,我们可以将权限管理模块封装到一个模块中,然后将实现的过程写在装饰器中,当有视图函数需要进行权限认证的时候,直接调用装饰器进行权限认证就可以
封装模块
from django.shortcuts import HttpResponse, render, redirect
from . import models
import re
class MenuHelper(object):
def __init__(self, request, username):
self.request = request # 当前用户的request对象
self.username = username # 当前用户名
self.current_url = request.path_info # 获取当前url
self.permission2action_dict = None # 当前用户的所有权限
self.menu_leaf_list = None # 用户权限菜单
self.menu_list = None # 所有菜单信息
self.session_data()
def session_data(self):
# 执行函数时候,先从session中获取用户的信息
permission_dict = self.request.session.get('permission_info')
if permission_dict: # 如果有,直接取出权限信息值,进行赋值
self.permission2action_dict = permission_dict['permission2action_dict']
self.menu_leaf_list = permission_dict['menu_leaf_list']
self.menu_list = permission_dict['menu_list']
else: # 如果没有,那么就要重新获取
# 获取当前用户的角色列表 第一个值
role_list = models.Role.objects.filter(user2role__u__username=self.username)
# 根据角色列表,获取到用户的所有权限列表,格式如下:这样有重复项目,进行匹配的时候比较困难
# v= [
# {'url': 'index.html', 'code': 'GET'},
# {'url': 'index.html', 'code': 'POST'}
# ]
permission2action_list = models.Permis