rbac组件权限分配


效果示例图:

 rbac/urls.py

from django.urls import re_path
from rbac.views import menu


urlpatterns = [
    # 权限分配
    re_path(r'^distribute/permissions/$', menu.distribute_permissions, name="distribute_permissions"),
]

rbac/views/menu.py

from django.shortcuts import render, redirect, HttpResponse
from rbac import models


def distribute_permissions(request):
    """
    权限分配
    :param request:
    :return:
    """
    user_id = request.GET.get("uid")
    user_object = models.Userinfo.objects.filter(id=user_id).first()
    if not user_object:
        user_id = None
    role_id = request.GET.get("rid")
    role_object = models.Role.objects.filter(id=role_id).first()
    if not role_object:
        role_id = None
    if request.method == "POST" and request.POST.get("type") == "role":
        role_id_list = request.POST.getlist("roles")
        # 用户和角色关系添加到第三章表(关系表)
        if not user_object:
            return HttpResponse("请选择用户...")
        user_object.roles.set(role_id_list)
    if request.method == "POST" and request.POST.get("type") == "permission":
        permission_id_list = request.POST.getlist("permissions")
        if not role_object:
            return HttpResponse("请选择角色...")
        role_object.permissions.set(permission_id_list)
    # 获取用户所拥有的所有角色
    if user_id:
        user_has_roles = user_object.roles.all()
    else:
        user_has_roles = []
    user_has_roles_dict = {item.id: None for item in user_has_roles}
    # 获取用户所拥有的所有权限
    # 如果选中了角色,优先显示角色所拥有的权限
    # 如果没有选角色,才显示用户所拥有的权限
    if role_object:  # 选择了角色
        user_has_permissions = role_object.permissions.all()
        user_has_permissions_dict = {item.id: None for item in user_has_permissions}
    elif user_object:  # 未选择角色,但选择了用户
        user_has_permissions = user_object.roles.filter(
            permissions__id__isnull=False
        ).values("id", "permissions").distinct()
        user_has_permissions_dict = {item["permissions"]: None for item in user_has_permissions}
    else:
        user_has_permissions_dict = {}
    all_user_list = models.Userinfo.objects.all().order_by("pk")
    all_role_list = models.Role.objects.all().order_by("pk")
    menu_permission_list = []
    # 获取所有的一级菜单
    all_menu_list = models.Menu.objects.values("id", "title")
    all_menu_dict = {}
    for item in all_menu_list:
        # all_menu_dict字典的值是item,引用的是内存地址,如果字典的值item发生变化了,那么all_menu_list的值也会发生变化
        item["children"] = []
        all_menu_dict[item["id"]] = item
    # 获取所有的二级菜单
    all_second_menu_list = models.Permission.objects.filter(menu__isnull=False).values("id", "title", "menu_id")
    all_second_menu_dict = {}
    for row in all_second_menu_list:
        row["children"] = []
        all_second_menu_dict[row["id"]] = row
        menu_id = row["menu_id"]
        all_menu_dict[menu_id]["children"].append(row)
    # 获取所有的三级菜单(不能做菜单的权限)
    all_permission_menu_list = models.Permission.objects.filter(menu__isnull=True).values("id", "title", "pid_id")
    for row in all_permission_menu_list:
        pid = row["pid_id"]
        if not pid:
            continue
        all_second_menu_dict[pid]["children"].append(row)
    return render(
        request,
        "rbac/distribute_permissions.html",
        {
            "all_user_list": all_user_list,
            "all_role_list": all_role_list,
            "all_menu_list": all_menu_list,
            "user_id": user_id,
            "user_has_roles_dict": user_has_roles_dict,
            "user_has_permissions_dict": user_has_permissions_dict,
            "role_id": role_id,
        }
    )


"""
all_menu_list = [{
    'id': 1,
    'title': '信息管理',
    'children': [{
        'id': 1,
        'title': '客户列表',
        'menu_id': 1,
        'children': [{
            'id': 2,
            'title': '添加客户',
            'pid_id': 1
        },
            {
                'id': 3,
                'title': '删除客户',
                'pid_id': 1
            },
            {
                'id': 4,
                'title': '修改客户',
                'pid_id': 1
            },
            {
                'id': 5,
                'title': '批量导入',
                'pid_id': 1
            },
            {
                'id': 6,
                'title': '下载模板',
                'pid_id': 1
            }]
    }]
},
    {
        'id': 2,
        'title': '用户管理',
        'children': [{
            'id': 7,
            'title': '账单列表',
            'menu_id': 2,
            'children': [{
                'id': 8,
                'title': '添加账单',
                'pid_id': 7
            },
                {
                    'id': 9,
                    'title': '删除账单',
                    'pid_id': 7
                },
                {
                    'id': 10,
                    'title': '修改账单',
                    'pid_id': 7
                }]
        }]
    },
    {
        'id': 17,
        'title': '权限管理',
        'children': [{
            'id': 16,
            'title': '角色列表',
            'menu_id': 17,
            'children': [{
                'id': 17,
                'title': '添加角色',
                'pid_id': 16
            },
                {
                    'id': 18,
                    'title': '编辑角色',
                    'pid_id': 16
                },
                {
                    'id': 19,
                    'title': '删除角色',
                    'pid_id': 16
                },
                {
                    'id': 20,
                    'title': '用户列表',
                    'pid_id': 16
                },
                {
                    'id': 21,
                    'title': '添加用户',
                    'pid_id': 16
                },
                {
                    'id': 22,
                    'title': '编辑用户',
                    'pid_id': 16
                },
                {
                    'id': 23,
                    'title': '删除用户',
                    'pid_id': 16
                },
                {
                    'id': 24,
                    'title': '重置密码',
                    'pid_id': 16
                }]
        },
            {
                'id': 25,
                'title': '菜单列表',
                'menu_id': 17,
                'children': [{
                    'id': 26,
                    'title': '添加菜单',
                    'pid_id': 25
                },
                    {
                        'id': 27,
                        'title': '编辑菜单',
                        'pid_id': 25
                    },
                    {
                        'id': 28,
                        'title': '删除菜单',
                        'pid_id': 25
                    },
                    {
                        'id': 29,
                        'title': '添加二级菜单',
                        'pid_id': 25
                    },
                    {
                        'id': 30,
                        'title': '编辑二级菜单',
                        'pid_id': 25
                    },
                    {
                        'id': 31,
                        'title': '删除二级菜单',
                        'pid_id': 25
                    },
                    {
                        'id': 32,
                        'title': '添加权限',
                        'pid_id': 25
                    },
                    {
                        'id': 33,
                        'title': '编辑权限',
                        'pid_id': 25
                    },
                    {
                        'id': 34,
                        'title': '删除权限',
                        'pid_id': 25
                    },
                    {
                        'id': 35,
                        'title': '批量操作权限',
                        'pid_id': 25
                    },
                    {
                        'id': 38,
                        'title': '批量删除权限',
                        'pid_id': 25
                    }]
            }]
    },
    {
        'id': 18,
        'title': '测试',
        'children': [{
            'id': 36,
            'title': '测试一',
            'menu_id': 18,
            'children': []
        }]
    }]
"""

rbac/templates/rbac/distribute_permissions.html

{% extends 'layout.html' %}

{% load rbac %}

{% block css %}
    <style>
        table {
            font-size: 12px;
        }

        .user-area ul {
            padding-left: 20px;
        }

        .user-area li {
            cursor: pointer;
            padding: 2px 0;
        }

        .user-area li a {
            display: block;
        }

        .user-area li.active {
            font-weight: bold;
            color: red;
        }

        .user-area li.active a {
            color: red;
        }

        .role-area tr td a {
            display: block;
        }

        .role-area tr.active {
            background-color: #f1f7fd;
            border-left: 3px solid #fdc00f;
        }

        .panel-body {
            font-size: 12px;
        }

        .permission-area tr.root {
            background-color: #f1f7fd;
        }

        .permission-area tr.root td i {
            margin: 3px;
        }

        .permission-area .node {

        }

        .permission-area .node input[type='checkbox'] {
            margin: 0 5px;
        }

        .permission-area .node .parent {
            padding: 5px 0;
        }

        .permission-area .node label {
            font-weight: normal;
            margin-bottom: 0;
            font-size: 12px;
        }

        .permission-area .node .children {
            padding: 0 0 0 20px;
        }

        .permission-area .node .children .child {
            display: inline-block;
            margin: 2px 5px;
        }

        .select-help {
            float: right;
        }

        .select-help label {
            font-weight: normal;
            cursor: pointer;
        }

        .select-help .check-all {
            float: left;
            display: inline-block;
            margin-right: 8px;
        }
    style>
{% endblock %}

{% block content %}
    <div class="luffy-container">
        {# 用户信息 #}
        <div class="col-md-3 user-area">
            <div class="panel panel-default">
                
                <div class="panel-heading">
                    <i class="fa fa-book" aria-hidden="true">i>
                    用户信息
                div>
                <div class="panel-body">
                    <ul>
                        {% for user in all_user_list %}
                            <li class="{% if user.id|safe == user_id %}active{% endif %}"><a
                                    href="?uid={{ user.id }}">{{ user.name }}a>li>
                        {% endfor %}
                    ul>
                div>
            div>
        div>
        {# 角色信息 #}
        <div class="col-md-3 role-area">
            <form method="post" action="">
                {% csrf_token %}
                <input type="hidden" name="type" value="role">
                <div class="panel panel-default">
                    
                    <div class="panel-heading">
                        <i class="fa fa-cog" aria-hidden="true">i>
                        角色信息
                        {% if user_id %}
                            <button href="#"
                                    class="right btn btn-success btn-xs"
                                    style="padding: 2px 8px; margin: -3px;">
                                <i class="fa fa-save" aria-hidden="true">i>
                                保存
                            button>
                        {% endif %}
                    div>
                    <div class="panel-body" style="color: #d4d4d4; padding: 10px 5px;">
                        提示:点击用户后才能为其分配角色
                    div>

                    
                    <table class="table">
                        <thead>
                        <tr>
                            <th>角色th>
                            <th>选项th>
                        tr>
                        thead>
                        <tbody>
                        {% for role in all_role_list %}
                            <tr class="{% if role.id|safe == role_id %}active{% endif %}">
                                <td>
                                    {% if user_id %}
                                        <a href="?uid={{ user_id }}&rid={{ role.id }}">{{ role.title }}a>
                                    {% else %}
                                        <a href="?rid={{ role.id }}">{{ role.title }}a>
                                    {% endif %}

                                td>
                                <td>
                                    <input type="checkbox" name="roles" value="{{ role.id }}"
                                           {% if role.id in user_has_roles_dict %}checked{% endif %}>
                                td>
                            tr>
                        {% endfor %}
                        tbody>
                    table>
                div>
            form>
        div>
        {# 权限分配 #}
        <div class="col-md-6 permission-area">
            <form method="post">
                {% csrf_token %}
                <input type="hidden" name="type" value="permission">
                <div class="panel panel-default">
                    
                    <div class="panel-heading">
                        <i class="fa fa-cogs" aria-hidden="true">i>
                        权限分配
                        {% if role_id %}
                            <button href="#"
                                    class="right btn btn-success btn-xs"
                                    style="padding: 2px 8px; margin: -3px;">
                                <i class="fa fa-save" aria-hidden="true">i>
                                保存
                            button>
                        {% endif %}
                    div>
                    <div class="panel-body" style="color: #d4d4d4; padding: 10px 5px;">
                        提示:点击角色之后才能为其分配权限
                    div>
                    <table class="table">
                        <tbody>
                        {% for item in all_menu_list %}
                            <tr class="root">
                                <td>
                                    <i class="fa fa-caret-down" aria-hidden="true">i>
                                    {{ item.title }}
                                    <div class="select-help">
                                        <div class="check-all">
                                            <label for="check_all_{{ item.id }}">全选label>
                                            <input id="check_all_{{ item.id }}" type="checkbox">
                                        div>
                                    div>
                                td>
                            tr>
                            {% if item.children %}
                                <tr class="node">
                                    <td>
                                        {% for node in item.children %}
                                            <div class="parent">

                                                <input id="permission_{{ node.id }}" name="permissions"
                                                       value="{{ node.id }}"
                                                       type="checkbox"
                                                       {% if node.id in user_has_permissions_dict %}checked{% endif %}>
                                                <label for="permission_{{ node.id }}">{{ node.title }} (菜单)label>
                                            div>
                                            <div class="children">
                                                {% for child in node.children %}
                                                    <div class="child">
                                                        <input type="checkbox" name="permissions" value="{{ child.id }}"
                                                               id="permission_{{ child.id }}"
                                                               {% if child.id in user_has_permissions_dict %}checked{% endif %}>
                                                        <label for="permission_{{ child.id }}">{{ child.title }}label>
                                                    div>
                                                {% endfor %}
                                            div>
                                        {% endfor %}
                                    td>
                                tr>
                            {% endif %}
                        {% endfor %}
                        tbody>
                    table>
                div>
            form>
        div>
    div>
    div>
{% endblock %}

{% block js %}
    <script type="text/javascript">
        $(function () {
            $(".check-all input:checkbox").change(function () {
                $(this).parents(".root").next().find(":checkbox").prop("checked", $(this).prop("checked"));
            })
        })
    script>
{% endblock %}

 

链接:https://pan.baidu.com/s/1Nf7Dcw3YUW6oKfsgPIMFBw
提取码:abab