权限的分配

一、权限分配

最终生成页面:

视图函数views.py

主要内容:从数据库中查到相应数据,构建层级结构。

  • 一级菜单
    • 二级菜单
      • 归属二级菜单的子权限
def distribute_permissions(request):
    """
    分配权限
    :param request:
    :return:
    """
    # 用户id
    uid = request.GET.get('uid')
    # 角色id
    rid = request.GET.get('rid')

    if request.method == 'POST' and request.POST.get('postType') == 'role':
        # 角色分配
        user = User.objects.filter(id=uid).first()
        if not user:
            return HttpResponse('用户不存在')
        # 为用户分配角色
        user.roles.set(request.POST.getlist('roles'))

    if request.method == 'POST' and request.POST.get('postType') == 'permission' and rid:
        # 为角色分配权限,点中角色才能分配权限
        role = Role.objects.filter(id=rid).first()
        if not role:
            return HttpResponse('角色不存在')
        # 为角色分配权限
        role.permissions.set(request.POST.getlist('permissions'))

    # 获取所有的用户
    user_list = User.objects.all()

    # 当前选中用户所拥有的角色
    user_has_roles = User.objects.filter(id=uid).values('id', 'roles')

    user_has_roles_dict = {item['roles']: None for item in user_has_roles}
    """
       user_has_roles_dict = { 角色的id:None  } 
       """
    # 所有的角色
    role_list = Role.objects.all()

    if rid:
        # 查出当前角色所拥有的权限
        role_has_permissions = Role.objects.filter(id=rid).values('id', 'permissions')
    elif uid and not rid:
        user = User.objects.filter(id=uid).first()
        if not user:
            return HttpResponse('用户不存在')
        # 查出前用户所拥有的角色所对应的权限
        role_has_permissions = user.roles.values('id', 'permissions')
    else:
        role_has_permissions = []

    role_has_permissions_dict = {item['permissions']: None for item in role_has_permissions}
    """"
       role_has_permissions_dict = { 权限的id :None  }
       """

    all_menu_list = []
    """
        all_menu_list  = [   
            { 'id', 'title', ‘children' : [  
                { 'id', 'title', 'menu_id' , 'children': [
                {'id', 'title', 'parent_id'}
            ] }
               ]   },
            {'id': None, 'title': '其他', 'children': [
             {'id', 'title', 'parent_id'}
            ]}
        ]
        """
    queryset = Menu.objects.values('id', 'title')
    menu_dict = {}
    """
        需要构成的分级数据结构
        menu_dict = { 一级菜单的id : { 'id', 'title', 
        ‘children' : [    
            { '二级菜单id', 'title', 'menu_id' , 'children': [
                {'id', 'title', 'parent_id'}
            ] }
         ]   },
            # 其他
             None : {'id': None, 'title': '其他', 'children': [
               {'id', 'title', 'parent_id'}
             ]}

        }
        """
    for item in queryset:
        item['children'] = []  # 放二级菜单  父权限
        menu_dict[item['id']] = item
        all_menu_list.append(item)

    other = {'id': None, 'title': '其他', 'children': []}
    all_menu_list.append(other)
    menu_dict[None] = other

    # 二级菜单  父权限
    root_permission = Permission.objects.filter(menu__isnull=False).values('id', 'title', 'menu_id')
    # 构建二级菜单权限数据结构
    root_permission_dict = {}
    """
      root_permission_dict =  { 父权限的id: { 'id', 'title', 'menu_id' , 'children': [
            {'id', 'title', 'parent_id'}
        ] }  }
        """
    for per in root_permission:
        per['children'] = []  # 放子权限
        nid = per['id']
        menu_id = per['menu_id']
        root_permission_dict[nid] = per
        menu_dict[menu_id]['children'].append(per)

    # 除了父权限的其他的权限
    node_permission = Permission.objects.filter(menu__isnull=True).values('id', 'title', 'parent_id')
    # 构建其他权限的数据结构
    for per in node_permission:
        pid = per['parent_id']
        if not pid:
            menu_dict[None]['children'].append(per)
            continue
        root_permission_dict[pid]['children'].append(per)

    return render(
        request,
        'rbac/distribute_permissions.html',
        {
            'user_list': user_list,
            'role_list': role_list,
            'user_has_roles_dict': user_has_roles_dict,
            'role_has_permissions_dict': role_has_permissions_dict,
            'all_menu_list': all_menu_list,
            'uid': uid,
            'rid': rid
        }
    )

模板rbac/distribute_permissions.html

主要有三块结构,注意数据的转义。数字key变为了字符串类型。

{% extends 'layout.html' %}
{% load rbac %}
{% block css %}
    <style>
        .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;
        }

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

        .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;
        }

        table {
            font-size: 12px;
        }

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

        .panel-body .form-control {
            font-size: 12px;
        }
    </style>
{% endblock %}

{% block content %}
    <div class="luffy-container">
        <div class="col-md-3 user-area">
            <div class="panel panel-default">
                <!-- Default panel contents -->
                <div class="panel-heading">
                    <i class="fa fa-address-book-o" aria-hidden="true"></i> 用户信息
                </div>

                <div class="panel-body">
                    <ul>
                        {% for user in user_list %}

                            <li class= {% if user.id|safe == uid %} "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">
                {% csrf_token %}
                <input type="hidden" name="postType" value="role">
                <div class="panel panel-default">
                    <!-- Default panel contents -->
                    <div class="panel-heading">
                        <i class="fa fa-book" aria-hidden="true"></i> 角色
                        {% if uid %}
                            <button type="submit" 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 role_list %}
                            <tr {% if role.id|safe == rid %} class="active"  {% endif %}>

                                <td><a href="?{% gen_role_url request role.id %}">{{ role.name }}</a></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="postType" value="permission">
                <div class="panel panel-default">
                    <!-- Default panel contents -->
                    <div class="panel-heading">
                        <i class="fa fa-sitemap" aria-hidden="true"></i> 权限分配
                        {% if rid %}
                            <button 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 }}</td>
                            </tr>
                            <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 role_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 id="permission_{{ child.id }}" name="permissions"
                                                           type="checkbox" value="{{ child.id }}"
                                                            {% if child.id in role_has_permissions_dict %}
                                                           checked {% endif %} >

                                                    <label for="permission_{{ child.id }}">{{ child.title }}</label>
                                                </div>
                                            {% endfor %}
                                        </div>
                                    {% endfor %}
                                </td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                </div>
            </form>
        </div>

    </div>
{% endblock %}
{% block js %}
    <script>
        $(function () {
            bindRootPermissionClick();
        });

        function bindRootPermissionClick() {
            $('.permission-area').on('click', '.root', function () {
                var caret = $(this).find('i');
                if (caret.hasClass('fa-caret-right')) {
                    caret.removeClass('fa-caret-right').addClass('fa-caret-down');
                    $(this).next().removeClass('hide');
                } else {
                    caret.removeClass('fa-caret-down').addClass('fa-caret-right');
                    $(this).next().addClass('hide');

                }
            })
        }
    </script>
{% endblock %}

templatetages.rbac.py中相关的simple_tag

# 获取当前角色id,然后给url添加一个rid参数
@register.simple_tag
def gen_role_url(request, rid):
    params = request.GET.copy()
    params['rid'] = rid
    return params.urlencode()
原文地址:https://www.cnblogs.com/zwq-/p/10205289.html