权限控制和菜单管理

权限控制到页面models.py登录后添加init

权限控制到一级菜单models.py登录后添加init_permission函数中间件前端inclusion_tag

权限控制到二级菜单models.py登录后添加init_permission函数中间件验证前端显示inclusion_tag

权限控制到路径导航(面包屑)models.py,登录后添加init_permission中间件前端显示inclusion_tag

权限控制到按钮models.py,登录后添加init_permission函数中间件前端inclusion_tag

终极权限控制

一、权限控制到页面

工作流程:
1. 登陆 中间件中通过白名单校验
2. 登陆成功 查询权限信息 保存在session中(json序列化)
3. 跳转至其他页面 进行权限的校验
1. 中间件中获取到session中的权限信息
2. 循环权限列表 用正则匹配当前的url地址
1. 匹配成功 return
2. 都没匹配成功 没有权限

1、models.py文件中

from django.db import models


# Create your models here.
class Permission(models.Model):
    """
    权限表
    """
    url = models.CharField(max_length=256, verbose_name='权限', unique=True)
    title = models.CharField(max_length=32, verbose_name='标题')

    def __str__(self):
        return self.title


class Role(models.Model):
    """
    角色表
    """
    name = models.CharField(max_length=32, verbose_name='角色名称')
    permissions = models.ManyToManyField('Permission', blank=True)

    def __str__(self):
        return self.name


class User(models.Model):
    """
    用户表
    """
    name = models.CharField(max_length=32, verbose_name='用户名')
    pwd = models.CharField(max_length=32, verbose_name='密码')
    roles = models.ManyToManyField('Role', blank=True)

    def __str__(self):
        return self.name

2、登录后添加

from django.shortcuts import render, redirect, reverse
from rbac import models
from django.conf import settings


def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        obj = models.User.objects.filter(name=user, pwd=pwd).first()
        if not obj:
            return render(request, 'login.html', {'error': '用户名或密码错误'})

        # 保存权限信息
        # 查询
        permission_list = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__title',
                                                                                        'permissions__url').distinct()
        request.session[settings.PERMISSION_SESSION_KEY] = list(permission_list)

        # 跳转
        return redirect(reverse('customer_list'))
    return render(request, 'login.html')

3、中间件验证

from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from django.shortcuts import HttpResponse, redirect, reverse
import re


class RbacMidlleware(MiddlewareMixin):

    def process_request(self, request):
        # 获取当前访问的url
        url = request.path_info

        # 白名单
        for i in settings.WHITE_LIST:
            if re.match(i, url):
                return

        # 获取权限信息
        permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
        print(permission_list)

        if not permission_list:
            return redirect(reverse('login'))

        # 权限的校验

        for i in permission_list:
            if re.match("^{}$".format(i['permissions__url']), url):
                return

        return HttpResponse('没有访问权限')

二、权限控制到一级菜单

1、models.py文件中

from django.db import models


# Create your models here.
class Permission(models.Model):
    """
    权限表
    is_menu
        True    表示当前的权限是一个菜单
        False   表示当前的权限不是一个菜单,只是普通的权限
    """
    url = models.CharField(max_length=256, verbose_name='权限', unique=True)
    title = models.CharField(max_length=32, verbose_name='标题')
    is_menu = models.BooleanField(verbose_name='是否是菜单', default=False)
    icon = models.CharField(max_length=56, verbose_name='图标', blank=True, null=True)

    def __str__(self):
        return self.title


class Role(models.Model):
    """
    角色表
    """
    name = models.CharField(max_length=32, verbose_name='角色名称')
    permissions = models.ManyToManyField('Permission', blank=True)

    def __str__(self):
        return self.name


class User(models.Model):
    """
    用户表
    """
    name = models.CharField(max_length=32, verbose_name='用户名')
    pwd = models.CharField(max_length=32, verbose_name='密码')
    roles = models.ManyToManyField('Role', blank=True)

    def __str__(self):
        return self.name

2、登录后添加

from django.shortcuts import render, redirect, reverse
from rbac import models
from rbac.service.permission import init_permission

def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        obj = models.User.objects.filter(name=user, pwd=pwd).first()
        if not obj:
            return render(request, 'login.html', {'error': '用户名或密码错误'})
        # 登陆成功后 权限信息的初始化(保存权限信息和菜单信息)
        init_permission(request,obj)
        # 跳转
        return redirect(reverse('customer_list'))
    return render(request, 'login.html')

3、init_permission函数

from django.conf import settings


def init_permission(request, obj):
    # 保存权限信息
    # 查询
    permission_query = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__title',
                                                                                     'permissions__url',
                                                                                     'permissions__is_menu',
                                                                                     'permissions__icon',
                                                                                     ).distinct()

    # 存放权限信息的列表
    permission_list = []
    # 存放菜单信息的列表
    menu_list = []

    for item in permission_query:
        # 将权限信息放入permission_list
        permission_list.append({'url': item['permissions__url']})

        # 将菜单的信息放入menu_list
        if item['permissions__is_menu']:
            menu_list.append({'url': item['permissions__url'], 'icon': item['permissions__icon'],
                              'title': item['permissions__title']})
    # 权限信息放入session
    request.session[settings.PERMISSION_SESSION_KEY] = permission_list

    # 菜单信息放入session
    request.session[settings.MENU_SESSION_KEY] = menu_list

4、中间件验证

 

from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from django.shortcuts import HttpResponse, redirect, reverse
import re


class RbacMidlleware(MiddlewareMixin):

    def process_request(self, request):
        # 获取当前访问的url
        url = request.path_info

        # 白名单
        for i in settings.WHITE_LIST:
            if re.match(i, url):
                return

        # 获取权限信息
        permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
        print(permission_list)

        # 登陆后没有权限
        if not permission_list:
            return redirect(reverse('login'))

        # 权限的校验
        for i in permission_list:
            if re.match("^{}$".format(i['url']), url):
                return

        return HttpResponse('没有访问权限')

5、前端显示

<div class="static-menu">
    {#                <a href="/customer/list/" class="active">#}
    {#                    <span class="icon-wrap"><i class="fa fa-connectdevelop"></i></span> 客户管理</a>#}
    {#                <a href="/payment/list/">#}
    {#                    <span class="icon-wrap"><i class="fa fa-code-fork"></i></span> 账单管理</a>#}
    {% for menu in menu_list %}

        <a href="{{ menu.url }}" class="{{ menu.class }}">
            <span class="icon-wrap "><i class="fa {{ menu.icon }}"></i></span> {{ menu.title }}</a>

    {% endfor %}


</div>

6、inclusion_tag

from django import template
import re

register = template.Library()

from django.conf import settings


# from luffy_permission import settings

@register.inclusion_tag('menu.html')
def menu(request):
    menu_list = request.session.get(settings.MENU_SESSION_KEY)

    url = request.path_info

    for item in menu_list:
        if re.match(item['url'], url):
            item['class'] = 'active'

    return {'menu_list': menu_list}

三、权限控制到二级菜单

1、models.py文件中

from django.db import models


class Menu(models.Model):
    """
    菜单表  一级菜单
    """
    name = models.CharField(max_length=32)
    icon = models.CharField(max_length=56, verbose_name='图标', blank=True, null=True)

    def __str__(self):
        return self.name


class Permission(models.Model):
    """
    权限表
    是否管联一级菜单
    权限 关联   菜单  表示 当前的权限是二级菜单
    权限 不关联 菜单  表示 当前的权限不是菜单
    """
    url = models.CharField(max_length=256, verbose_name='权限', unique=True)
    title = models.CharField(max_length=32, verbose_name='标题')
    menu = models.ForeignKey('Menu', blank=True, null=True,)

    def __str__(self):
        return self.title


class Role(models.Model):
    """
    角色表
    """
    name = models.CharField(max_length=32, verbose_name='角色名称')
    permissions = models.ManyToManyField('Permission', blank=True)

    def __str__(self):
        return self.name


class User(models.Model):
    """
    用户表
    """
    name = models.CharField(max_length=32, verbose_name='用户名')
    pwd = models.CharField(max_length=32, verbose_name='密码')
    roles = models.ManyToManyField('Role', blank=True)

    def __str__(self):
        return self.name

2、登录后添加

from django.shortcuts import render, redirect, reverse
from rbac import models
from rbac.service.permission import init_permission

def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        obj = models.User.objects.filter(name=user, pwd=pwd).first()
        if not obj:
            return render(request, 'login.html', {'error': '用户名或密码错误'})
        # 登陆成功后 权限信息的初始化(保存权限信息和菜单信息)
        init_permission(request,obj)
        # 跳转
        return redirect(reverse('customer_list'))
    return render(request, 'login.html')

3、init_permission函数

from django.conf import settings


def init_permission(request, obj):
    # 保存权限信息
    # 查询
    permission_query = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__title',
                                                                                     'permissions__url',
                                                                                     'permissions__menu__name',
                                                                                     'permissions__menu__icon',
                                                                                     'permissions__menu__id',
                                                                                     ).distinct()

    print(permission_query)
    # 存放权限信息的列表
    permission_list = []
    # 存放菜单信息的列表
    menu_dict = {}

    for item in permission_query:
        # 将权限信息放入permission_list
        permission_list.append({'url': item['permissions__url']})

        # 放入菜单信息
        menu_id = item.get('permissions__menu__id')

        if not menu_id:
            continue

        if menu_id not in menu_dict:
            menu_dict[menu_id] = {'name': item['permissions__menu__name'], 'icon': item['permissions__menu__icon'],
                                  'children': [{'title': item['permissions__title'], 'url': item['permissions__url']}]}
        else:
            menu_dict[menu_id]['children'].append(
                {'title': item['permissions__title'], 'url': item['permissions__url']})

    # 权限信息放入session
    request.session[settings.PERMISSION_SESSION_KEY] = permission_list

    # 菜单信息放入session
    request.session[settings.MENU_SESSION_KEY] = menu_dict

4、中间件验证 

from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from django.shortcuts import HttpResponse, redirect, reverse
import re


class RbacMidlleware(MiddlewareMixin):

    def process_request(self, request):
        # 获取当前访问的url
        url = request.path_info

        # 白名单
        for i in settings.WHITE_LIST:
            if re.match(i, url):
                return

        # 获取权限信息
        permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
        print(permission_list)

        # 登陆后没有权限
        if not permission_list:
            return redirect(reverse('login'))

        # 权限的校验
        for i in permission_list:
            if re.match("^{}$".format(i['url']), url):
                return

        return HttpResponse('没有访问权限')

5、前端显示

<div class="multi-menu">
    {% for menu in menu_list %}
        <div class="item">
            <div class="title"><i class="fa {{ menu.icon }}"></i> {{ menu.name }}</div>
            <div class="body">
                {% for child in menu.children %}
                    <a href="{{ child.url }}"> {{ child.title }}</a>
                {% endfor %}

            </div>
        </div>
    {% endfor %}
</div>

6、inclusion_tag

from django import template
import re
register = template.Library()
from django.conf import settings
# from luffy_permission import settings
@register.inclusion_tag('menu.html')
def menu(request):
    menu_dict = request.session.get(settings.MENU_SESSION_KEY)
    return {'menu_list': menu_dict.values()}

四、权限控制到路径导航(面包屑)

1、models.py文件中

from django.db import models


class Menu(models.Model):
    """
    菜单表  一级菜单
    """
    name = models.CharField(max_length=32)
    icon = models.CharField(max_length=56, verbose_name='图标', blank=True, null=True)
    weight = models.IntegerField(default=1)

    def __str__(self):
        return self.name


class Permission(models.Model):
    """
    权限表
    menu_id
        有   表示当前的权限是二级菜单  也是父权限
        没有  就是一个普通的权限

    parent_id
        有    表示当前的权限是一个子权限
        没有  父权限

    """
    url = models.CharField(max_length=256, verbose_name='权限', unique=True)
    title = models.CharField(max_length=32, verbose_name='标题')
    menu = models.ForeignKey('Menu', blank=True, null=True, )
    parent = models.ForeignKey('Permission',blank=True, null=True,)

    def __str__(self):
        return self.title


class Role(models.Model):
    """
    角色表
    """
    name = models.CharField(max_length=32, verbose_name='角色名称')
    permissions = models.ManyToManyField('Permission', blank=True)

    def __str__(self):
        return self.name


class User(models.Model):
    """
    用户表
    """
    name = models.CharField(max_length=32, verbose_name='用户名')
    pwd = models.CharField(max_length=32, verbose_name='密码')
    roles = models.ManyToManyField('Role', blank=True)

    def __str__(self):
        return self.name

2、登录后添加

from django.shortcuts import render, redirect, reverse
from rbac import models
from rbac.service.permission import init_permission

def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        obj = models.User.objects.filter(name=user, pwd=pwd).first()
        if not obj:
            return render(request, 'login.html', {'error': '用户名或密码错误'})
        # 登陆成功后 权限信息的初始化(保存权限信息和菜单信息)
        init_permission(request,obj)
        # 跳转
        return redirect(reverse('customer_list'))
    return render(request, 'login.html')

3、init_permission函数

from django.conf import settings


def init_permission(request, obj):
    # 保存权限信息
    # 查询
    permission_query = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__title',
                                                                                     'permissions__url',
                                                                                     'permissions__menu__name',
                                                                                     'permissions__menu__icon',
                                                                                     'permissions__menu__weight',
                                                                                     'permissions__menu__id',
                                                                                     'permissions__id',
                                                                                     'permissions__parent_id',
                                                                                     ).distinct()

    print(permission_query)
    # 存放权限信息的列表
    permission_dict = {}
    # 存放菜单信息的列表
    menu_dict = {}

    for item in permission_query:
        # 将权限信息放入permission_list
        permission_dict[item['permissions__id']] = {'url': item['permissions__url'],
                                                    'pid': item['permissions__parent_id'],
                                                    'id': item['permissions__id'],
                                                    'title': item['permissions__title'],
                                                    }

        # 放入菜单信息
        menu_id = item.get('permissions__menu__id')

        # 不是菜单
        if not menu_id:
            continue

        if menu_id not in menu_dict:
            menu_dict[menu_id] = {'name': item['permissions__menu__name'],
                                  'icon': item['permissions__menu__icon'],
                                  'weight': item['permissions__menu__weight'],
                                  'children': [{'id': item['permissions__id'], 'title': item['permissions__title'],
                                                'url': item['permissions__url']}]}
        else:
            menu_dict[menu_id]['children'].append(
                {'id': item['permissions__id'], 'title': item['permissions__title'], 'url': item['permissions__url']})

    # 权限信息放入session
    request.session[settings.PERMISSION_SESSION_KEY] = permission_dict

    # 菜单信息放入session
    request.session[settings.MENU_SESSION_KEY] = menu_dict

4、中间件验证 

from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from django.shortcuts import HttpResponse, redirect, reverse
import re


class RbacMidlleware(MiddlewareMixin):

    def process_request(self, request):
        # 获取当前访问的url
        url = request.path_info

        # 白名单
        for i in settings.WHITE_LIST:
            if re.match(i, url):
                return

        # 获取权限信息
        permission_dict = request.session.get(settings.PERMISSION_SESSION_KEY)
        print(permission_dict)

        # 登陆后没有权限
        if not permission_dict:
            return redirect(reverse('login'))

        request.current_menu_id = None

        request.breadcrumb_list = [
            {'title': '首页', 'url': '/index/'}
        ]

        # 需要登录但是不需要权限校验
        for i in settings.NO_PERMISSION_LIST:
            if re.match(i, url):
                return

        # 权限的校验
        for item in permission_dict.values():
            # {url   id   pid    }
            if re.match("^{}$".format(item['url']), url):
                # 要显示二级菜单的id  权限的id
                pid = item.get('pid')
                id = item.get('id')
                if pid:
                    # 当前访问的权限   是子权限  找父权限进行显示
                    request.current_menu_id = pid

                    request.breadcrumb_list.append(
                        {'title': permission_dict[str(pid)]['title'], 'url': permission_dict[str(pid)]['url']})
                    request.breadcrumb_list.append({'title': item['title'], 'url': item['url']})

                else:
                    # 当前访问的权限   是父权限  二级菜单   找自己进行显示

                    request.current_menu_id = id
                    request.breadcrumb_list.append({'title': item['title'], 'url': item['url']})

                return

        return HttpResponse('没有访问权限')

5、前端显示

<div>
    <ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;">

        {% for breadcrumb in breadcrumb_list %}
            {% if forloop.last %}
                <li class="active">{{ breadcrumb.title }}</li>
            {% else %}
                <li><a href="{{ breadcrumb.url }}">{{ breadcrumb.title }}</a></li>

            {% endif %}
        {% endfor %}

    </ol>
</div>

6、inclusion_tag

from django import template
import re
from collections import OrderedDict
register = template.Library()
from django.conf import settings
# from luffy_permission import settings

@register.inclusion_tag('menu.html')
def menu(request):
    menu_dict = request.session.get(settings.MENU_SESSION_KEY)
    order_dic = OrderedDict()
    for key in sorted(menu_dict, key=lambda i: menu_dict[i]['weight'], reverse=True):
        order_dic[key] = item = menu_dict[key]
        item['class'] = 'hide'
        for i in item['children']:
            # if re.match("^{}$".format(i['url']), request.path_info):
            if i['id'] == request.current_menu_id:
                i['class'] = 'active'
                item['class'] = ''
                break
    return {'menu_list': order_dic.values()}
@register.inclusion_tag('breadcrumb.html')
def breadcrumb(request):
    return {'breadcrumb_list': request.breadcrumb_list}

五、权限控制到按钮

1、models.py文件中

from django.db import models


class Menu(models.Model):
    """
    菜单表  一级菜单
    """
    name = models.CharField(max_length=32)
    icon = models.CharField(max_length=56, verbose_name='图标', blank=True, null=True)
    weight = models.IntegerField(default=1)

    def __str__(self):
        return self.name


class Permission(models.Model):
    """
    权限表
    menu_id
        有   表示当前的权限是二级菜单  也是父权限
        没有  就是一个普通的权限

    parent_id
        有    表示当前的权限是一个子权限
        没有  父权限

    """
    url = models.CharField(max_length=256, verbose_name='权限', unique=True)
    title = models.CharField(max_length=32, verbose_name='标题')
    name = models.CharField(max_length=32, verbose_name='URL别名',unique=True)
    menu = models.ForeignKey('Menu', blank=True, null=True, )
    parent = models.ForeignKey('Permission', blank=True, null=True, )

    def __str__(self):
        return self.title


class Role(models.Model):
    """
    角色表
    """
    name = models.CharField(max_length=32, verbose_name='角色名称')
    permissions = models.ManyToManyField('Permission', blank=True)

    def __str__(self):
        return self.name


class User(models.Model):
    """
    用户表
    """
    name = models.CharField(max_length=32, verbose_name='用户名')
    pwd = models.CharField(max_length=32, verbose_name='密码')
    roles = models.ManyToManyField('Role', blank=True)

    def __str__(self):
        return self.name

2、登录后添加

from django.shortcuts import render, redirect, reverse
from rbac import models
from rbac.service.permission import init_permission

def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        obj = models.User.objects.filter(name=user, pwd=pwd).first()
        if not obj:
            return render(request, 'login.html', {'error': '用户名或密码错误'})
        # 登陆成功后 权限信息的初始化(保存权限信息和菜单信息)
        init_permission(request,obj)
        # 跳转
        return redirect(reverse('customer_list'))
    return render(request, 'login.html')

3、init_permission函数

from django.conf import settings


def init_permission(request, obj):
    # 保存权限信息
    # 查询
    permission_query = obj.roles.all().filter(permissions__url__isnull=False).values('permissions__title',
                                                                                     'permissions__url',
                                                                                     'permissions__menu__name',
                                                                                     'permissions__menu__icon',
                                                                                     'permissions__menu__weight',
                                                                                     'permissions__menu__id',
                                                                                     'permissions__id',
                                                                                     'permissions__parent_id',
                                                                                     'permissions__name',
                                                                                     'permissions__parent__name',
                                                                                     ).distinct()

    print(permission_query)
    # 存放权限信息的列表
    permission_dict = {}
    # 存放菜单信息的列表
    menu_dict = {}

    for item in permission_query:
        # 将权限信息放入permission_list
        permission_dict[item['permissions__name']] = {'url': item['permissions__url'],
                                                    'pid': item['permissions__parent_id'],
                                                    'pname': item['permissions__parent__name'],
                                                    'id': item['permissions__id'],
                                                    'title': item['permissions__title'],
                                                    }

        # 放入菜单信息
        menu_id = item.get('permissions__menu__id')

        # 不是菜单
        if not menu_id:
            continue

        if menu_id not in menu_dict:
            menu_dict[menu_id] = {'name': item['permissions__menu__name'],
                                  'icon': item['permissions__menu__icon'],
                                  'weight': item['permissions__menu__weight'],
                                  'children': [{'id': item['permissions__id'], 'title': item['permissions__title'],
                                                'url': item['permissions__url']}]}
        else:
            menu_dict[menu_id]['children'].append(
                {'id': item['permissions__id'], 'title': item['permissions__title'], 'url': item['permissions__url']})

    # 权限信息放入session
    request.session[settings.PERMISSION_SESSION_KEY] = permission_dict

    # 菜单信息放入session
    request.session[settings.MENU_SESSION_KEY] = menu_dict

4、中间件验证 

from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from django.shortcuts import HttpResponse, redirect, reverse
import re


class RbacMidlleware(MiddlewareMixin):

    def process_request(self, request):
        # 获取当前访问的url
        url = request.path_info

        # 白名单
        for i in settings.WHITE_LIST:
            if re.match(i, url):
                return

        # 获取权限信息
        permission_dict = request.session.get(settings.PERMISSION_SESSION_KEY)
        print(permission_dict)

        # 登陆后没有权限
        if not permission_dict:
            return redirect(reverse('login'))

        request.current_menu_id = None

        request.breadcrumb_list = [
            {'title': '首页', 'url': '/index/'}
        ]

        # 需要登录但是不需要权限校验
        for i in settings.NO_PERMISSION_LIST:
            if re.match(i, url):
                return

        # 权限的校验
        for item in permission_dict.values():
            # {url   id   pid    }
            if re.match("^{}$".format(item['url']), url):
                # 要显示二级菜单的id  权限的id
                pid = item.get('pid')
                id = item.get('id')
                pname = item.get('pname')
                if pid:
                    # 当前访问的权限   是子权限  找父权限进行显示
                    request.current_menu_id = pid

                    request.breadcrumb_list.append(
                        {'title': permission_dict[pname]['title'], 'url': permission_dict[pname]['url']})
                    request.breadcrumb_list.append({'title': item['title'], 'url': item['url']})

                else:
                    # 当前访问的权限   是父权限  二级菜单   找自己进行显示

                    request.current_menu_id = id
                    request.breadcrumb_list.append({'title': item['title'], 'url': item['url']})

                return

        return HttpResponse('没有访问权限')

5、前端显示

<div>
    <ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;">

        {% for breadcrumb in breadcrumb_list %}
            {% if forloop.last %}
                <li class="active">{{ breadcrumb.title }}</li>
            {% else %}
                <li><a href="{{ breadcrumb.url }}">{{ breadcrumb.title }}</a></li>

            {% endif %}
        {% endfor %}

    </ol>
</div>

6、inclusion_tag

from django import template
import re
from collections import OrderedDict
register = template.Library()
from django.conf import settings
# from luffy_permission import settings
@register.inclusion_tag('menu.html')
def menu(request):
    menu_dict = request.session.get(settings.MENU_SESSION_KEY)
    order_dic = OrderedDict()
    for key in sorted(menu_dict, key=lambda i: menu_dict[i]['weight'], reverse=True):
        order_dic[key] = item = menu_dict[key]
        item['class'] = 'hide'
        for i in item['children']:
            # if re.match("^{}$".format(i['url']), request.path_info):
            if i['id'] == request.current_menu_id:
                i['class'] = 'active'
                item['class'] = ''
                break

    return {'menu_list': order_dic.values()}

六、终极权限控制

#rbac组件的应用
1. 拷贝rbac组件到新的项目中,并且要注册
2. 数据库的迁移
   1. 先删除rbac下migrations下的除了init之外的文件
   2. 修改用户表
      1. 
         class User(models.Model):
             """
             用户表
             """
             # name = models.CharField(max_length=32, verbose_name='用户名')
             # pwd = models.CharField(max_length=32, verbose_name='密码')
             roles = models.ManyToManyField(Role, blank=True)   # 关联用类         
             class Meta:
                 abstract = True     # 执行数据库迁移命令时不会生成具体的表,这张表做基类
      2. 在新项目中用户表要去继承User
      3. 执行数据库迁移的命令
3. 在根的urlconf中添加rbac的路由
   url(r'rbac/', include('rbac.urls', namespace='rbac'))
4. 角色管理  添加角色
5. 菜单管理   给权重
6. 权限管理
   1. 录入权限信息
   2. 分配好菜单和父权限

7. 分配权限
   1. 给角色分配权限
   2. 给用户分配角色
8. 加上权限的控制 
   1. 加中间件
   2. 权限的配置放在settings中

      # 权限存放在session中的KEY
      PERMISSION_SESSION_KEY = 'permission'      
      # 菜单存放在session中的KEY
      MENU_SESSION_KEY = 'menu'
     
      WHITE_LIST = [
          r'^/login/$',
          r'^/reg/$',
          r'^/admin/.*',
      ]
      
      NO_PERMISSION_LIST = [
          r'^/index/$',
      ]

   3. 修改登录函数s
      校验成功后权限信息的初始化
      from rbac.service.permission import init_permission
      # 登录成功后
      init_permission(request,obj)
9. 应用上二级菜单
   在母板中使用 menu inclusion_tag
   {% load rbac %}
   {% menu request %}
   引入css、js的效果
10. 路径导航
    {% breadcrumb request %}
11. 权限控制到按钮
{% load rbac %}
{% if request|has_permission:'add_customer' %}
    <a class="btn btn-sm btn-primary" style="margin-bottom: 5px"
       href="{% reverse_url request 'add_customer' %}">添加</a>
{% endif %}

 

 

posted @ 2019-06-06 11:23  海予心  阅读(3026)  评论(2编辑  收藏  举报