主要内容:
1 添加字典的两种方法:
li1 = [] dic = {} for i in range(10): dic['num'] = i #下次循环的时候会把前边的num值给替换了, 并把该字典加入到列表中. 先替换后添加 li1.append(dic) print(li1) print('..', li1) 第二种方法 li = [] for i in range(10): li.append({'num': i}) # 每次创建了一个新的字典, print(li)
2 总的流程:
如果用户进行登录, 现在先执行中间件的方法, login对应的白名单, 此时结束中间件, 进入到路由匹配, 执行login函数, 登录成功, 把对应的用户的权限写入到seesion中, 然后进入到customer页面, 此时先进行到中间件, 把seession里的数据取出来, 此时有权限列表和菜单列表, 进行url配, 如果通过, 结束, 进入到路由匹配, 执行相应的视图函数, 进入到对应的页面, 由于要生成动态的菜单, 所以要使用inclusion_tag标签, 对模板进行动态的修改, 此时把模板中的两个a标签菜单的展示的代码段复制到一个文件中, 执行到这的时候, 走对应的方法, 然后就得到了菜单展示的页面.
3 一级菜单的展示:
流程:
1 在models中建表, 用户表, 角色表, 权限表, ()
多个用户可以对应一个角色, 也可以是一个用户有多个角色, 但由于从用户查角色的比较常见, 所以在用户中设置了多对多的关系,
然后由角色查权限: 所以在角色中设置了多对多的关系
class Permission(models.Model): title = models.CharField(max_length=32, verbose_name='标题') url = models.CharField(max_length=32, verbose_name='权限') 一级菜单的展示, 二级菜单加了Menu表 is_memu = models.BooleanField(default=False, verbose_name='是否是标题') icon = models.CharField(max_length=32, verbose_name='图标', null=True, blank=True) class Role(models.Model): name = models.CharField(max_length=32, verbose_name='角色名') permissions = models.ManyToManyField(to='Permission', verbose_name='角色所拥有当权限', blank=True) class User(models.Model): username = models.CharField(max_length=32, verbose_name='用户名') password = models.CharField(max_length=32, verbose_name='密码') roles = models.ManyToManyField(to='Role', verbose_name='用户所拥有的角色', blank=True) def __str__(self): return self.username class Meta: verbose_name = '用户表' verbose_name_plural = '用户表'
注意: 写完表后执行python manage.py makemigrations, python manage.py migrate
如果执行不了, 把对应的数据库中的django_migrations表对应的变更记录给删除了.
2 : admin中写入以下代码:
from django.contrib import admin from rbac import models class PermissionAdmin(admin.ModelAdmin): 在admin中用于展示的 list_display = ['title', 'url', 'is_menu', 'icon'] 用于编辑的字段, 在admin中显示 list_editable = ['url', 'is_menu', 'icon'] 注册下面的表 admin.site.register(models.Permission, PermissionAdmin) admin.site.register(models.Role) admin.site.register(models.User)
2 创建一个超级用户: python manage.py createsuperuser , 进入到admin, 填写相应的数据
3 写代码;
1, 写登录逻辑, 如果登录成功, 跳转到customer界面, 此时需要对该用户所对应的权限做个校验, 获取权限的表, 和菜单的表,
2, 菜单表的获取, 有用户获取权限queryset的过程中, 此时跨角色表查询出是否是菜单的字段和图标的字段, 此时需要进行判断,
3, 如果有菜单的字段, 此时对应的布尔值是ture, 往菜单表中加入字典把对应当key设置了, 方便在中间件获取的时候, 取到
menu_list = [] for item in permission_query: permission_list.append({'url': item['permissions__url']}) if item.get('permissions__is_menu'): menu_list.append({'url': item['permissions__url'], 'icon': item['permissions__icon'], 'title': item['permissions__title']}) # 将菜单信息写入到session request.session[settings.MENU_SESSION_KEY] = menu_list
4, 模板渲染的时候, 由于要动态的生成, 所以用到了inclusion_tag,
流程 - 先创建一个templatetags包--- 创建一个mytags.py文件 -- 然后倒入from django import template,,register = template.Library()两句话, --- 写对应的函数逻辑,-- 函数上定义一个装饰器方法@register.inclusion_tag('rbac/menu.html') --- 把需要动态修改的html代码段放在此处 ----返回一个字典, 返回的字典对此html代码段进行渲染--把渲染后的页面交给
引用此标签的页面. -----引用标签的方法{% load mytags%} {% menu request%}传request给页面的时候要用.
4 二级菜单的展示:
此时加了一个菜单表, 有标题, 和 图标
此时对权限的表进行了修改, 在权限表中加了menu字段, 设置了 外键
由于二级菜单可以对应的没有一级菜单, 多以, 在外键中写入,null = ture, blank = ture
class Menu(models.Model): title = models.CharField(max_length=32, unique=True) icon = models.CharField(max_length=32, verbose_name='图标', null=True, blank=True) class Permission(models.Model): title = models.CharField(max_length=32, verbose_name='标题') url = models.CharField(max_length=32, verbose_name='权限') menu = models.ForeignKey('Menu', null=True, blank=True)
5 把rbac写成组件, 的使用方法:
1 拷贝rbac组件 到 新的项目中 并注册APP
2 配置权限的相关信息
# ###### 权限相关的配置 ######
PERMISSION_SESSION_KEY = 'permissions'
MENU_SESSION_KEY = 'menus'
WHITE_URL_LIST = [
r'^/login/$',
r'^/logout/$',
r'^/reg/$',
r'^/admin/.*',
]
3 创建跟权限相关的表(删除之前的迁移文件的记录,)执行命令:
python manage.py makemigrations
python manage.py migrate
4 录入权限信息:
创建超级用户, 录入权限信息, 创建角色, 给角色分权限, 给用户分角色
5 在登录成功之后 写入权限和菜单的信息 到session中
6 配置上中间件 进行权限的校验.