• Django权限管理系统设计分析


    权限管理顾名思义,其实就是角色控制权限的系统,每个用户对应一个角色,每个角色有对应的权限,比如公司会有CEO,总监,销售经理,销售员,每个人的权限都不一样,那我们给他展示的url也都不同

    一、首先创建项目,再创建一个名为rbac的app

      修改配置文件settings,将css以及js、img等放到static文件夹下

    二、表结构设计

     设计表:

      创建五个类,七张表:

      菜单表,权限组,权限表,用户表,角色表,

      角色表和权限表是多对多的关系(一个角色可以有多个权限,一个权限可以对应多个角色)
         用户表和角色表是多对多的关系(一个用户可以有多个角色,一个角色有多个用户)

      

    models.py

    from django.db import models
    
    
    # 菜单组
        class Menu(models.Model):
        title = models.CharField(verbose_name='菜单组', max_length=32)
    
        class Meta:
            verbose_name_plural = '菜单表'
    
        def __str__(self):
            return self.title
    
    
    # 权限组
    class Group(models.Model):
        title = models.CharField(verbose_name='权限标题', max_length=32)
        menu = models.ForeignKey(verbose_name='所属菜单', to='Menu', default=1)
    
        class Meta:
            verbose_name_plural= '权限组表'
    
        def __str__(self):
            return self.title
    
    
    # 权限表
    class Permission(models.Model):
    
        title = models.CharField(verbose_name='标题', max_length=128)
        url = models.CharField(verbose_name='含正则表达式的URL', max_length=128)
        menu_gp = models.ForeignKey(verbose_name='组内权限', to='Permission', null=True, blank=True, related_name='x1')
        code = models.CharField(verbose_name='权限代号', max_length=32)
        group = models.ForeignKey(verbose_name='所属组', to='Group')
    
        class Meta:
            verbose_name_plural= '权限表'
    
        def __str__(self):
            return self.title
    
    # 用户表
    class UserInfo(models.Model):
    
        username = models.CharField(verbose_name='用户名', max_length=32)
        password = models.CharField(verbose_name='密码',max_length=64)
        user_role = models.ManyToManyField(verbose_name='用户角色', to='Role', blank=True)
    
        class Meta:
            verbose_name_plural= '用户表'
    
        def __str__(self):
            return self.username
    
    # 角色表
    class Role(models.Model):
    
        position = models.CharField(verbose_name='职位', max_length=32)
        permissions = models.ManyToManyField(verbose_name='角色权限', to='Permission', blank=True)
    
        class Meta:
            verbose_name_plural= '角色表'
    
        def __str__(self):
            return self.position
    

    我们一般是先看到的是列表页面,在这个页面上是否显示添加,是否显示编辑,是否显示删除,都是需要判断的, 有无添加权限,有无删除权限,有无编辑权限,我们可以给每一个url一个代号,将代号取出来放在一个列表里面

    dict = {
    	'5': {
    		'codes': ['list', 'add', 'edit', 'del'],
    		'urls': ['/userinfo/', '/userinfo/add/', '/userinfo/(\d+)/change/', '/userinfo/(\d+)/delete/']
    	},
    	'1': {
    		'codes': ['list', 'add', 'edit', 'del'],
    		'urls': ['/order/', '/order/add/', '/order/(\d+)/change/', '/order/(\d+)/delete/']
    	}
    }
    

    把这个字典存到session中当你访问页面的时候我就知道你有什么权限一个url对应一个code 多个url对应一个组.

    三、通过Django-admin录入数据

    先创建一个超级用户:python3 manage.py createsuperuser
    用户名:root
    密码:a123456

     在admin.py中做如下配置:

    from django.contrib import admin
    from . import models
    
    admin.site.register(models.Menu)
    admin.site.register(models.UserInfo)
    admin.site.register(models.Role)
    admin.site.register(models.Permission)
    admin.site.register(models.Group)
    

     

    models.py中做如下配置,就可以在添加的时候显示中文了。

    # 菜单组
    class Menu(models.Model):
        title = models.CharField(verbose_name='菜单组', max_length=32)
    
        class Meta:
            verbose_name_plural = '菜单表'
    
        def __str__(self):
            return self.title
    

      

     

     四、编写登录

      利用Django的中间件进行控制,没有登录的用户不能直接访问内部的url,而且只能访问admin,login,index这三个url,将其设置为白名单,用户登录成功后,将用户信息方法哦session里边,进行权限访问时去session里边读取,如果有的话进行url跳转,如果没有的话返回‘’无权访问‘’

       1.在settings内设置白名单:

        

      2.编写中间件控制时,必须继承MiddlewareMixin这个类

       

    # -*- coding:utf-8 -*-
    # !/usr/bin/python
    from django.shortcuts import redirect, HttpResponse
    from django.conf import settings
    import re
    
    class MiddlewareMixin(object):
    
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MiddlewareMixin, self).__init__()
    
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                response = self.process_request(request)
            if not response:
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                response = self.process_response(request, response)
            return response
    
    
    class RbacMiddleware(MiddlewareMixin):
    
        def process_request(self, request):
    
            # 1.当前请求的URL
            current_request_url = request.path_info
    
            # 2.处理白名单
            for url in settings.VALID_URL_LIST:
                if re.match(url, current_request_url):
                    return None
    
            # 3.获取session中保存的权限信息
            permission_dict = request.session.get(settings.XX)
            print(permission_dict)
            if not permission_dict:
                return redirect(settings.RBAC_LOGIN_URL)
            flag = False
            for group_id, values in permission_dict.items():
                for url in values["urls"]:
                    if re.match(url, current_request_url):
                        flag = True
                        break
                if flag:
                    break
            if not flag:
                return HttpResponse("无权访问")
    

      

  • 相关阅读:
    Android中Handler与Message的简单实例
    折腾蛋疼的Ubuntu1204LTS的U盘安装
    sgs_intro
    把杀某程序封装成sh
    boost 程序库完全开发_ch4_utility
    VS2005 warning C4819处理办法(提示代码页有不兼容的字符)
    Ubuntu1204LTS下xynxyc编译Emacs24.02
    当VS05调试赋值不对时,小心只是IDE的watch在骗你.....
    很好的boost学习资料
    C++实现Creational Singleton模式
  • 原文地址:https://www.cnblogs.com/Crazy-lyl/p/9219281.html
Copyright © 2020-2023  润新知