django 菜單權限


一.什么是權限

 能做哪些事情,不能做哪些事情,可以做的權限

二.設計權限

思路:

web應用中,所謂的權限,其實就是一個用戶能夠訪問的url,通過對用戶訪問的url進行控制,從而實現對用戶權限的控制.

每個用戶代表不同的的角色,每個角色具有不同的權限.

一個用戶可以有多重角色,多個人也可以是一種角色(比如說一個公司可以有多個銷售),所以說,用戶與角色之間的關系是多對多的關系.

一個角色能夠擁有多個權限,一個權限也可以分配給多個角色;所以說角色和權限的關系也是多對多的關系.

 

 

 

三.權限實現

建立表關系

具體代碼如下:

from django.db import models


class Menu(models.Model):
    title = models.CharField(max_length=32)
    icon = models.CharField(max_length=32)
    weight = models.IntegerField(default=1, verbose_name='權重')
class Permission(models.Model):
    """
    權限表
    """
    title = models.CharField(max_length=32, verbose_name='標題')
    url = models.CharField(max_length=32, verbose_name='權限')
    
    menu = models.ForeignKey(to='Menu',on_delete=models.CASCADE,default=0,blank=True,null=True)
    pid = models.ForeignKey('self',on_delete=models.CASCADE,null=True,verbose_name='父權限')

    name = models.CharField(max_length=32, null=True, blank=True, unique=True)
    
    class Meta:
        verbose_name_plural = '權限表'
        verbose_name = '權限表'
    
    def __str__(self):
        return self.title


class Role(models.Model):
    name = models.CharField(max_length=32, verbose_name='角色名稱')
    permissions = models.ManyToManyField(to='Permission', verbose_name='角色所擁有的權限', blank=True)
    
    def __str__(self):
        return self.name


class User(models.Model):
    """
    用戶表
    """
    name = 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.name

 

獲取權限信息

每次當用戶一登錄是,就應該獲取當前的用戶所擁有的所有權限信息.

當然了首先需要構建的應該是當前用戶的權限列表中.構建出來之后將其存入到session中,以便於之后的權限校驗

這里還需要構造出我們創建菜單想要的數據結構,以便於之后創建二級菜單.

然后我們構建出來的菜單數據結構和權限列表如下所示:

permission_list[{
    'url': '/customer/',
    'pid': None,
    'title': '全部客戶',
    'id': 1
}, {
    'url': '/customers/list/',
    'pid': None,
    'title': '共有客戶',
    'id': 2
}, {
    'url': '/mycustomers/',
    'pid': None,
    'title': '我的客戶',
    'id': 3
}, {
    'url': '/consult_records/',
    'pid': None,
    'title': '客戶跟進記錄',
    'id': 4
}, {
    'url': '/customer/count/',
    'pid': None,
    'title': '客戶成單統計',
    'id': 5
}, {
    'url': '/enrollment/',
    'pid': None,
    'title': '報名情況',
    'id': 6
}, {
    'url': '/enrollment/add/',
    'pid': 6,
    'title': '添加報名記錄',
    'id': 7
}, {
    'url': '/enrollment/edit/(\\d+)',
    'pid': 6,
    'title': '修改報名記錄',
    'id': 8
}, {
    'url': '/ClassStudyRecord/list/',
    'pid': None,
    'title': '班級學習記錄',
    'id': 9
}, {
    'url': '/ClassStudyRecord/add/',
    'pid': 9,
    'title': '添加學習記錄',
    'id': 10
}, {
    'url': '/studentstudyrecord/edit/(\\d+)/',
    'pid': 9,
    'title': '添加記錄',
    'id': 11
}, {
    'url': '/rbac/role/list/',
    'pid': None,
    'title': '角色管理',
    'id': 12
}, {
    'url': '/rbac/role/add/',
    'pid': 12,
    'title': '添加角色',
    'id': 13
}, {
    'url': '/rbac/role/edit/(\\d+)',
    'pid': 12,
    'title': '修改角色',
    'id': 14
}, {
    'url': '/rbac/role/del/(\\d+)',
    'pid': 12,
    'title': '刪除角色',
    'id': 15
}, {
    'url': '/rbac/menu/list/',
    'pid': None,
    'title': '菜單管理',
    'id': 16
}, {
    'url': '/rbac/menu/add/',
    'pid': 16,
    'title': '添加目錄',
    'id': 17
}, {
    'url': '/rbac/menu/edit/(\\d+)',
    'pid': 16,
    'title': '修改目錄',
    'id': 18
}, {
    'url': '/rbac/permission/distrbute/',
    'pid': None,
    'title': '分配權限',
    'id': 19
}, {
    'url': '/rbac/permission/tree/',
    'pid': 19,
    'title': '權限樹',
    'id': 20
}, {
    'url': '/index/',
    'pid': None,
    'title': '首頁',
    'id': 21
}, {
    'url': '/logout/',
    'pid': None,
    'title': '注銷',
    'id': 22
}, {
    'url': '/customers/add/',
    'pid': 1,
    'title': '添加客戶',
    'id': 23
}, {
    'url': '/customers/add/',
    'pid': 2,
    'title': '添加客戶',
    'id': 24
}, {
    'url': '/customers/add/',
    'pid': 3,
    'title': '添加客戶',
    'id': 25
}, {
    'url': '/customer/del/(\\d+)/',
    'pid': 1,
    'title': '刪除客戶',
    'id': 26
}, {
    'url': '/customer/del/(\\d+)/',
    'pid': 2,
    'title': '刪除客戶',
    'id': 27
}, {
    'url': '/customer/del/(\\d+)/',
    'pid': 3,
    'title': '刪除客戶',
    'id': 28
}, {
    'url': '/customers/edit/(\\d+)',
    'pid': 1,
    'title': '修改客戶',
    'id': 29
}, {
    'url': '/customers/edit/(\\d+)',
    'pid': 2,
    'title': '修改客戶',
    'id': 30
}, {
    'url': '/customers/edit/(\\d+)',
    'pid': 3,
    'title': '修改客戶',
    'id': 31
}, {
    'url': '/consult_records/add/',
    'pid': 4,
    'title': '添加客戶跟進記錄',
    'id': 32
}, {
    'url': '/consult_records/(\\d+)',
    'pid': 4,
    'title': '修改客戶跟進記錄',
    'id': 33
}, {
    'url': '/del_consult/(\\d+)',
    'pid': 4,
    'title': '刪除客戶跟進記錄',
    'id': 34
}]
權限列表
permission_menu_dic {
    '2': {
        'menu_title': '客戶管理',
        'menu_icon': 'nav-icon fa fa-dashboard',
        'childern': [{
            'title': '全部客戶',
            'url': '/customer/'
        }, {
            'title': '共有客戶',
            'url': '/customers/list/'
        }, {
            'title': '我的客戶',
            'url': '/mycustomers/'
        }, {
            'title': '客戶跟進記錄',
            'url': '/consult_records/'
        }, {
            'title': '客戶成單統計',
            'url': '/customer/count/'
        }]
    },
    '3': {
        'menu_title': '報名管理',
        'menu_icon': 'nav-icon fa fa-table',
        'childern': [{
            'title': '報名情況',
            'url': '/enrollment/'
        }]
    },
    '4': {
        'menu_title': '成績管理',
        'menu_icon': 'nav-icon fa fa-th',
        'childern': [{
            'title': '班級學習記錄',
            'url': '/ClassStudyRecord/list/'
        }]
    },
    '5': {
        'menu_title': '權限管理',
        'menu_icon': 'nav-icon fa fa-tree',
        'childern': [{
            'title': '角色管理',
            'url': '/rbac/role/list/'
        }, {
            'title': '菜單管理',
            'url': '/rbac/menu/list/'
        }, {
            'title': '分配權限',
            'url': '/rbac/permission/distrbute/'
        }]
    }
}
permission_menu_dic {
    '2': {
        'menu_title': '客戶管理',
        'menu_icon': 'nav-icon fa fa-dashboard',
        'childern': [{
            'title': '全部客戶',
            'url': '/customer/',
            'active': 'active'
        }, {
            'title': '共有客戶',
            'url': '/customers/list/'
        }, {
            'title': '我的客戶',
            'url': '/mycustomers/'
        }, {
            'title': '客戶跟進記錄',
            'url': '/consult_records/'
        }, {
            'title': '客戶成單統計',
            'url': '/customer/count/'
        }],
        'style': 'display:block',
        'class': 'menu-open'
    },
    '3': {
        'menu_title': '報名管理',
        'menu_icon': 'nav-icon fa fa-table',
        'childern': [{
            'title': '報名情況',
            'url': '/enrollment/'
        }]
    },
    '4': {
        'menu_title': '成績管理',
        'menu_icon': 'nav-icon fa fa-th',
        'childern': [{
            'title': '班級學習記錄',
            'url': '/ClassStudyRecord/list/'
        }]
    },
    '5': {
        'menu_title': '權限管理',
        'menu_icon': 'nav-icon fa fa-tree',
        'childern': [{
            'title': '角色管理',
            'url': '/rbac/role/list/'
        }, {
            'title': '菜單管理',
            'url': '/rbac/menu/list/'
        }, {
            'title': '分配權限',
            'url': '/rbac/permission/distrbute/'
        }]
    }
}
菜單數據

 具體構建代碼如下:

from rbac.models import Role


def initial_sesson(user,request):
    """
    功能:將當前登錄人的所有權限錄入session中
    :param user: 當前登錄人
    """
    # 查詢當前登錄人的所有權限列表
    # 查看當前登錄人的所有角色
    # ret=Role.objects.filter(user=user)
    permissions = Role.objects.filter(userinfo=user).values("permissions__url",
                                                        "permissions__title",
                                                        'permissions__pid',
                                                        'permissions__pk',
                                                        "permissions__menu__pk",
                                                        "permissions__menu__title",
                                                        "permissions__menu__icon",
                                                        ).distinct()
    print('permissions',permissions)


    permission_list = []
    permission_menu_dic = {}

    for item in permissions:
        # 構建權限列表
        permission_list.append({
            'url':item["permissions__url"],
            'pid':item["permissions__pid"],
            'title':item["permissions__title"],
            'id':item["permissions__pk"],

        })
        # 構建菜單權限列表
        if item["permissions__menu__pk"]:
            if not permission_menu_dic.get(item['permissions__menu__pk']):

                permission_menu_dic[item['permissions__menu__pk']] = {
                    'menu_title':item['permissions__menu__title'],
                    'menu_icon':item['permissions__menu__icon'],
                    'childern':[{
                        'title':item['permissions__title'],
                        'url':item['permissions__url']
                    }]
                }
            else:

                permission_menu_dic[item['permissions__menu__pk']]['childern'].append({
                    'title':item['permissions__title'],
                    'url':item['permissions__url']
                })

    print('permission_menu_dic',permission_menu_dic)
    # 將當前登錄人的權限列表注入session中
    request.session["permission_list"] = permission_list
    # 將當前登錄人的菜單權限列表注入session中
    print("permission_list",permission_list)
    request.session["permission_menu_dic"] = permission_menu_dic

 構建菜單:

這里使用的django的自定義標簽incluSion_tags.

首先創建一個templatetags文件夾,(注意這個文件夾的名字必須是這個名字)

其次創建一個py文件,這個文件名可以隨意.

代碼如下:

from django.utils.safestring import mark_safe
from django.template import Library
import re
register =Library()


@register.inclusion_tag("rbac/menu.html")
def get_menu_styles(request):
    permission_menu_dic = request.session.get("permission_menu_dic")
    print('permission_menu_dic',permission_menu_dic)
    for val in permission_menu_dic.values():
        for item in val.get('childern'):
            if  re.search('^{}$'.format(item['url']),request.path):
                val['style'] = 'display:block'
                val['class'] = 'menu-open'
                item['active'] = 'active'
    print("permission_menu_dic",permission_menu_dic)
    return {"permission_menu_dic":permission_menu_dic}
自定義菜單標簽

 這里還需要一個菜單的模板:

    {% for item in permission_menu_dic.values %}
        <li class="nav-item has-treeview {{ item.class }}">
            <a href="#" class="nav-link">
                 <i class="{{ item.menu_icon }}"></i>
                <p>
                   {{ item.menu_title }}
                    <i class="right fa fa-angle-left"></i>
                </p>
            </a>

            <ul class="nav nav-treeview" style="{{ item.style }}">
                {% for foo in item.childern %}
                    <li class="nav-item">
                    <a href="{{ foo.url }}" class="nav-link {{ foo.active }}">
                        <i class="fa fa-circle-o nav-icon"></i>
                        <p>{{ foo.title }}</p>
                    </a>
                </li>

                {% endfor %}
            </ul>
        </li>
    {% endfor %}
menu

 這里的菜單css和js可以自己進行定制.我這里使用的是bootstrap的模板.

 

自此,菜單以及菜單權限就構建完成!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM