22-1 rbac权限设计

一 表结构设计

22-1 rbac权限设计22-1 rbac权限设计

 1 from django.db import models 2  3 # Create your models here. 4 from django.db import models 5  6 # Create your models here. 7  8  9 # 用户表10 class UserInfo(models.Model):11     username = models.CharField(max_length=16, verbose_name="用户名")12     password = models.CharField(max_length=32, verbose_name="密码")13     roles = models.ManyToManyField(to="Role", null=True, blank=True)14     # null=TRUE是告诉数据库这个字段可以为空,blank=True告诉djangoadmin可以不填15 16     # 显示具体的内容17     def __str__(self):18         return self.username19 20     # 让字段显示中文21     class Meta:22         verbose_name = "用户表"23         verbose_name_plural = verbose_name24 25 26 # 角色27 class Role(models.Model):28     title = models.CharField(max_length=32, verbose_name="角色名称")29     permissions = models.ManyToManyField(to="Permission")30 31     def __str__(self):32         return self.title33 34     class Meta:35         verbose_name = "角色表"36         verbose_name_plural = verbose_name37 38 39 # 权限表40 class Permission(models.Model):41     title = models.CharField(max_length=16, verbose_name="权限名称")42     url = models.CharField(max_length=255, verbose_name="URL")43     is_menu = models.BooleanField(default=False, verbose_name="可作为菜单展示")44     icon = models.CharField(max_length=16, verbose_name="菜单图标", null=True, blank=True)45 46     def __str__(self):47         return self.title48 49     class Meta:50         verbose_name = "权限表"51         verbose_name_plural = verbose_name

View Code

二 创建rbac权限管理项目

1. 为了实现项目结构的解耦,把权限系统单独写成一个app
  1. 创建APP
            Django中创建app的步骤
           1. python manage.py startapp rbac  在terminal终端里面运行
           2. 在settings.py中注册app
    rbac.apps.RbacConfig
2. 执行两条命令,把表结构同步到数据库把创建数据库的语句写在rbac的models文件里
  1. python manage.py makemigrations
  2. python manage.py migrate
3. 录入数据
  借助Django Admin
  Django admin的用法
  1. 创建超级用户,用来登陆admin管理后台
  python manage.py createsuperuser
  2. 将我们自己写的表注册到Django admin中
  在app/admin.py中按照固定的格式注册model

       如下:

   

 1 from django.contrib import admin 2 from rbac import models 3 # 注册用户表 4 admin.site.register(models.UserInfo) 5 #注册角色表 6 admin.site.register(models.Role) 7  8  9 # 自定义一个权限管理类10 class PermissionAdmin(admin.ModelAdmin):11     # 告诉django admin在页面上展示我这张表的那些字段12     list_display = ["title","url","is_menu","icon"]13     # 在列表页面可以编辑url14     list_editable = ["url","icon","is_menu"]15 16 17 admin.site.register(models.Permission,PermissionAdmin)

三 权限的查询

权限查询的代码最好能拿出来单独封装一个函数,这样方便你以后可以直接用你写的rbac这个权限管理

1 在rbac目录下面新建一个python package 名字可以随便叫,然后新建一个py文件,名字也可以随便叫我这里叫:permission.py

22-1 rbac权限设计22-1 rbac权限设计

 1 from django.conf import settings 2  3  4 def init_permission(request, user_obj): 5     ''' 6 在session中初始化权限信息和菜单信息的函数 7     :param request: 请求对象 8     :param user_obj:当前登录用户 9     :return:10     '''11 12     # user_obj.roles.all()那到当前用户的所有角色13     ret = user_obj.roles.all().values("permissions__url",14                                       "permissions__icon",15                                       "permissions__is_menu",16                                       "permissions__title"17                                       ).distinct()  # 取到去重之后的权限18     # 定义一个权限列表19     permission_list = []20     # 定义一个专门用来存放当前用户菜单的列表21     menu_list = []22     for item in ret:23         print(item)  # item是个大列表24         permission_list.append({"permissions__url": item["permissions__url"]})  # 添加到权限列表25         if item["permissions__is_menu"]:  # 如果为真26             menu_list.append({27                 "title": item["permissions__title"],28                 "icon": item["permissions__icon"],29                 "url": item["permissions__url"]30             })31 32     # 将用户权限列表信息,存到session中33     request.session[settings.PERMISSION_SESSION_KEY] = permission_list34     # 把当前用户的所有菜单存放到sessioin35     request.session[settings.MENU_SESSION_KEY] = menu_list

View Code

2 setting.py文件配置

# 设置白名单PERMISSION_WHITE_URL=["/login/","/admin/.*",
]#权限列表PERMISSION_SESSION_KEY="permission_list"#菜单列表MENU_SESSION_KEY="menu_list"

四 权限校验

应该将权限的校验功能放在中间件中的process_request()方法

1 在rbac目录下面新建一个python package包 middleware ,然后建一个rbac.py文件,名字可以随便取

22-1 rbac权限设计22-1 rbac权限设计

 1 ''' 2 自定义rbac中间件 3 ''' 4 from django.utils.deprecation import  MiddlewareMixin 5 from django.shortcuts import redirect,HttpResponse,render 6 import re 7 from django.conf import settings 8  9 class RBACMiddleware(MiddlewareMixin):10     def process_request(self,request):11         '''12         自定义权限校验的中间件13         :param request: 请求对象14         :return:15         '''16         # 1 取到当前这次请求访问的url是什么17         url=request.path_info   # request.get_full_path()18         # 过滤白名单19         for item in settings.PERMISSION_WHITE_URL:20             reg="^{}$".format(item)21             if re.match(reg,url):22                 return None23         # 取到当前用户的权限列表24         permission_list=request.session.get(settings.PERMISSION_SESSION_KEY,None)25         # 进行权限校验26         if  permission_list is None:27             # 用户没登录28             return redirect("/login/")29         for i in permission_list:30             reg="^{}$".format(i['permissions__url'])31             if re.match(reg,url):32                 break33         else:34             return HttpResponse("你没有此权限")

View Code

2 然后在setting.py文件里注册一下

'rbac.middleware.rbac.RBACMiddleware',

 五 项目登录函数的引用就是导入刚才封装好的初始化权限的函数

'''跟用户相关的视图都写在这里'''from django.shortcuts import redirect, render, HttpResponsefrom rbac.models import UserInfofrom rbac.service.permission import init_permissiondef login(request):
    error_msg = ""if request.method == "POST":# 取用户名和密码username = request.POST.get("username")
        pwd = request.POST.get("password")# 验证user_obj = UserInfo.objects.filter(username=username, password=pwd).first()if user_obj:# 登录成功# 调用封装好的初始化函数里面含有权限列表和显示菜单            init_permission(request,user_obj)return redirect("/customer/list/")else:
            error_msg = "用户名或密码错误"return render(request, "login.html")

六 页面中引用模板语言

1 首先在rbac下面新建一个python packages名字为templatetags(名字必须是这个)然后新建一个py文件,名字随意,我这里叫ooxx

filename 就是将你返回的结果给那个页面调用,show_menu就是你自定义的模板语言的名字

from django import templatefrom luffy_permission import settings

register = template.Library()


@register.inclusion_tag(filename="my_menu.html")def show_menu(request):
# menu_list是你从session里面获取的用户的菜单列表
     menu_list = request.session[settings.MENU_SESSION_KEY]return {"menu_list": menu_list}  # 把menu_list返回给my_menu.html这个页面

2 新建一个my_menu.html的文件,名字跟filename后面的一致,在rbac目录下新建一个templates

这个里面的menu_list就是你上面自定义的的返回结果,menu.icon代表是图标字段,menu.title代表是菜单名字

1 {% for menu in menu_list %}2     <a href="{{ menu.url }}" class="active">3         <span class="icon-wrap"><i class="fa {{ menu.icon }}"></i></span> {{ menu.title }}</a>4 5 {% endfor %}

 

3 让你真正给用户看的html页面去引用ooxx,就是在菜单的div里面加上这个 request是show_menu的一个参数

      <div class="static-menu">{% load ooxx %}
                {% show_menu request %}</div>

 七 rbac权限目录结构

22-1 rbac权限设计

 

新的项目中如何引用rbac权限管理##########################################################


1. 拷贝rbac这个app到项目中
2. 把rbac/migrations目录下的迁移记录都删掉
3. 在项目中注册rbac这个app
4. 创建数据库迁移(执行那两条命令)

1. python manage.py makemigrations2. python manage.py migrate

5. 注册admin,录入数据 --> 自动发现并录入权限URL
6. 在登录流程中初始化权限信息,配置登录函数引用封装好的初始化权限

22-1 rbac权限设计22-1 rbac权限设计

from django.shortcuts import render, HttpResponse, redirectfrom django.conf import settingsfrom rbac.service.permission import init_permissionfrom rbac.models import UserInfo# Create your views here.def login(request):if request.method == "POST":
        username = request.POST.get("username")
        pwd = request.POST.get("password")

        user_obj = UserInfo.objects.filter(username=username, password=pwd).first()if user_obj:# 登录成功# 初始化权限信息            init_permission(request, user_obj)return redirect("/book_list/")return render(request, "login.html")def book_list(request):return render(request, "book_list.html")def book_add(request):return render(request, "book_add.html")

View Code

7. 注册中间件
8. 在settings.py中设置权限相关的配置项

# 设置白名单PERMISSION_WHITE_URL=["/login/","/admin/.*",
]#权限列表PERMISSION_SESSION_KEY="permission_list"#菜单列表MENU_SESSION_KEY="menu_list"

9 在html列表页面引用

   {% load ooxx %}
    {% show_menu request %}

 





上一篇:20210429解决lombok插件存在,但是运行报不存在异&启动服务其实显示log日志写入地址找不到&Orcale树形结构查找


下一篇:MySQL Load data多种使用方法