以权限管理模块中角色和权限、用户和角色均为多对多关系,一个角色可以匹配多个权限,一个用户可以有多个角色。
角色表中设置:
permissions = models.ManyToManyField("Permission")
用户表中设置:
roles = models.ManyToManyField(to='Role',verbose_name='角色')
具体model.py如下:
# _*_ encoding:utf-8 _*_
from django.db import models
from django.contrib.auth.models import AbstractUser
class Menu(models.Model):
"""
菜单
"""
title = models.CharField(max_length=32, unique=True,verbose_name=u'菜单',default='')
icon = models.CharField(max_length=10,verbose_name=u'菜单图标',null=True, blank=True,default='')
parent = models.ForeignKey("Menu", null=True, blank=True,on_delete=models.CASCADE,default='')
# 定义菜单间的自引用关系
# 权限url 在 菜单下;菜单可以有父级菜单;还要支持用户创建菜单,因此需要定义parent字段(parent_id)
# blank=True 意味着在后台管理中填写可以为空,根菜单没有父级菜单
def __str__(self):
# 显示层级菜单
title_list = [self.title]
p = self.parent
while p:
title_list.insert(0, p.title)
p = p.parent
return '-'.join(title_list)
class Meta:
verbose_name = u"菜单"
verbose_name_plural = verbose_name
class Permission(models.Model):
"""
权限
"""
title = models.CharField(max_length=32, unique=True,verbose_name = u"权限",default='')
url = models.CharField(max_length=128, unique=True,default='')
icon = models.CharField(max_length=10, verbose_name=u'权限图标', null=True, blank=True,default='')
menu = models.ForeignKey("Menu", null=True, blank=True,on_delete=models.CASCADE)
def __str__(self):
# 显示带菜单前缀的权限
return '{menu}---{permission}'.format(menu=self.menu, permission=self.title)
class Meta:
verbose_name = u"权限"
verbose_name_plural = verbose_name
class Role(models.Model):
"""
角色:绑定权限
"""
title = models.CharField(max_length=32, unique=True,verbose_name = u"角色")
permissions = models.ManyToManyField("Permission")
# 定义角色和权限的多对多关系
def __str__(self):
return self.title
class Meta:
verbose_name = u"角色"
verbose_name_plural = verbose_name
class UserInfo(models.Model):
"""
用户:划分角色
"""
username = models.CharField(max_length=32,verbose_name=u"用户名",default='')
password = models.CharField(max_length=8,verbose_name=u"密码",default='123456')
real_name = models.CharField(max_length=50, verbose_name=u"真实姓名", default="")
mobile = models.CharField(max_length=11, null=True, blank=True, verbose_name=u"手机号",default='')
roles = models.ManyToManyField(to='Role',verbose_name='角色')
class Meta:
verbose_name = u"用户"
verbose_name_plural = verbose_name
def __str__(self):
return self.username
数据库中会根据多对多关系自动生成关联表:
image.png
此时对用户和角色的一些操作不仅涉及本身pemission、role、userinfo三张表,对于关联表也要进行一定的操作。
下面view.py中以角色和权限的增删改查为例:
# 增加角色
def addrole(request):
if request.method == 'POST':
title = request.POST.get("title")
permissions_id = request.POST.getlist("permissions")
isRepeat = len(Role.objects.filter(title=title).values())
# 不重复则新增数据
if isRepeat == 0:
obj = Role.objects.create(title=title)
obj.permissions.add(*permissions_id) #关系表中增加该角色的权限
menu_list = Menu.objects.all()
user_list = UserInfo.objects.all()
role_list = Role.objects.all()
return render(request, "rbac/permissionToUser.html",{'role_list': role_list,"menu_list": menu_list,"user_list":user_list, "isRepeat": isRepeat})
# 角色权限修改
def editrole(request):
if request.method == 'POST':
role_id = request.POST.get("id")
permissions_id = request.POST.getlist("permissions") #获取新的权限列表
obj = Role.objects.get(id=role_id) #获取角色对象
obj.permissions.clear() #将该角色之前的权限清空
obj.permissions.add(*permissions_id) #重新为该角色添加权限
return HttpResponseRedirect('/rbac/permissions/')
# 角色删除
def deleterole(request):
if request.method == 'POST':
role_id = request.POST.get("id")
role_obj = Role.objects.get(id=role_id)
if len(role_obj.userinfo_set.all()):
NotDeletRole = 1
return HttpResponse(json.dumps({
"NotDeletRole": NotDeletRole
}))
else:
obj = Role.objects.get(id=role_id) #获取角色对象
obj.permissions.clear() #该角色的权限清空
Role.objects.filter(id=role_id).delete() #然后删除该角色
NotDeletRole = 0
return HttpResponse(json.dumps({
"NotDeletRole": NotDeletRole
}))
网友评论