• Django


     一、权限分配

      需求:为用户分配角色,为角色分配权限,如下图效果:

    1、视图代码:

    from django.shortcuts import render
    from django.http import JsonResponse
    
    from rbac.models import User, Role, Permission
    
    def distribute_permissions(request):
        """
        分配权限
        """
        uid = request.GET.get('uid')
        user = User.objects.filter(id=uid)
        rid = request.GET.get('rid')
    
        # 保存为用户分配的角色
        if request.method == 'POST' and request.POST.get('postType') == 'role':
            r_lst = request.POST.getlist("roles")
            user.first().roles.set(r_lst)
    
        # 保存为角色分配的权限
        if request.method == 'POST' and request.POST.get('postType') == 'permission':
            p_lst = request.POST.getlist("permissions_id")
            Role.objects.filter(pk=rid).first().permissions.set(p_lst)
    
        user_list = User.objects.all()
        role_list = Role.objects.all()
    
        if uid:   # 选中某一用户,则显示其对应角色
            role_id_list= User.objects.get(pk=uid).roles.all().values_list("pk")
            role_id_list = [item[0] for item in role_id_list]
    
            if rid:   # 点击某一角色,则显示其对应的权限
                per_id_list = Role.objects.filter(pk=rid).values_list("permissions__pk").distinct()
            else:  # 不点击角色,则显示选中用户对应角色拥有的权限
                per_id_list = User.objects.get(pk=uid).roles.values_list("permissions__pk").distinct()
            per_id_list = [item[0] for item in per_id_list]
    
        return render(request, 'distribute_permission.html', locals())
    
    # 显示权限表,ajax请求对应的视图函数
    def permissions_tree(request):
        permissions = Permission.objects.values("pk", "title", "url", "menu__title", "menu__pk", "pid_id")
        return JsonResponse(list(permissions), safe=False)

      注意:JsonResponse传入一个非字典类型的数据结构时,需要设置safe=False。

    2、模板代码

      1)显示用户表相关代码

    <div class="am-panel-bd">
        <ul class="user_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>

      2)显示角色表相关代码

    <table class="am-table table-main mytable">
        <thead>
        <tr class="am-primary">
            <th>角色</th>
            <th>选择</th>
        </tr>
        </thead>
        <tbody>
            {% for role in role_list %}
            <tr class={% if role.id|safe == rid %}"am-danger"{% endif %}>
                {% load my_tags %}
                <td>
            <a href="?{% get_role_url request role.id %}">{{ role.title }}</a>
            </td>
                <td>
                    {% if role.id in role_id_list %}
                    <input type="checkbox" name="roles" value="{{ role.id }}" checked />
                    {% else %}
                    <input type="checkbox" name="roles" value="{{ role.id }}" />
                    {% endif %}
                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

      3)显示权限表相关代码

    <div class="am-panel-hd">
        <span style="margin-left: 6px;">权限分配</span>
        {% if rid %}
            <button type="submit" class="am-btn am-fr"></i>保存</button>
        {% endif %}
    </div>
    <p class="per_tips">提示:点击角色后才能为其分配权限</p>
    <div class="am-panel-bd mypanel">
        <table class="am-table table-main mytable">
            <tbody id="tbd">
            <!-- 通过文档加载时发送ajax请求获取用户权限,ajax代码如下 -->
            </tbody>
        </table>
    </div>
    
    {% block js %}
        <script>
        $.ajax({
            url:"/rbac/permissions_tree/",
            type:"get",
            success:function (res) {
                console.log(res);
                $.each(res, function (i, permission) {   // 渲染权限树形结构
                    console.log(i, permission);
                    var menu_title = permission["menu__title"];
                    var menu_pk = permission["menu__pk"];
                    var url = permission["url"];
                    var parent_id = permission["pid_id"];
                    var pk = permission["pk"];
                    var title = permission["title"];
                    if (menu_title){   // 如果是菜单权限,即menu_id有值,pid_id为空
                 // 所属的一级菜单已经存在,则直接追加权限
                        if($("#menu_"+menu_pk).length){
                            var s = `
                                <tr id="per_${pk}">
                                    <td class="">
                                        <div class="">
                                            <label>
                <input name="permissions_id" value="${pk}" type="checkbox">
                <span>${title}</span>
                          </label>
                                        </div>
                                    </td>
                                </tr>
                                `;
                            $("#menu_"+menu_pk).parent().append(s);
                        }else {  // 所属的一级菜单不存在,即渲染菜单,又渲染权限
                            var s = `
                                <tr class="" id="menu_${menu_pk}">
                    <td>${menu_title}</td>
                     </tr>
                                <tr id="per_${pk}">
                                    <td class="">
                                        <div class="">
                                            <label>
                <input name="permissions_id" value="${pk}" type="checkbox">
                <span>${title}</span>
                          </label>
                                        </div>
                                    </td>
                                </tr>
                                `;
                            $("#tbd").append(s);
                        }
                    }else {  // 如果不是菜单权限,即menu_id为空,pid_id有值
                        var s = `
                                <div class="">
                                    <label>
                <input name="permissions_id" value="${pk}" type="checkbox">
                <span>${title}</span>
                      </label>
                                </div>
                            `;
                        $("#per_"+parent_id+" td").append(s);
                    }
                });
    
            // 选中角色对应的权限
                var per_id_list = {{ per_id_list }}
                $.each(per_id_list, function (i, j) {
                    console.log($("[value='"+j+"']")[0]);
                    $("#tbd [value='"+j+"']").prop("checked", true);
                })
    
            }
        })
        </script>
    {% endblock %}

    3、思路分析

      此需求难点是将权限表渲染在页面,有两种方案:在前端处理和在后端构建数据结构。

      后端构建数据结构比较复杂,涉及到联动等。所以我们可以从前端入手,充分利用jquery的选择器,根据从数据库拿到的权限信息,用jquery技术渲染出来自己需要的结构。

    二、将权限组件移植到CRM项目

    (1) 先将rbac组件移植到新的项目中;

    (2) 将settings中 INSTALLED_APPS 中加入"rbac";

    (3) 将新项目的用户表与rbac下的User表一对一关联;

    (4) 数据迁移;

    (5) 在登录成功后引入rbac下的initial_session方法,做登录用户的权限信息存储(注意user对象);

    (6) 在setting是中引入rbac下的权限校验中间件;

    (7) 在项目的base模板中引入菜单样式,渲染显示;

      

  • 相关阅读:
    屏蔽 优酷广告
    First Adventures in Google Closure -摘自网络
    Closure Compiler(封闭编辑器), Closure Inspector, Closure Templates, 封闭图书馆(Closure Library) Google- 摘自网络
    据说几年前,微信之父张小龙有一次入京到龙泉寺散心,心中关于微信的产品困惑久久不得解。无聊中,张小龙与寺中扫地僧攀谈起来,发现对方居然懂得技术和产品,深入聊天之后,张小龙震惊于对方的才学与见识,虚心请教,之后闭关七天回到深圳,微信终于大成。
    一个PHP书单 -摘自网络
    关于protel 99se 汉化后某些菜单消失的解决方法
    Protel画完原理图检查的时候出现了这些错误 #1 Error Multiple Net Identifiers
    protel99 se中出现许多Backup of 文件,修改过保存时,总会出现备份文件,怎么才能取消这一设置?
    protel 99se 加载库文件 files not recognised 解决办法-转
    Hosts 文件的作用
  • 原文地址:https://www.cnblogs.com/li-li/p/9998041.html
Copyright © 2020-2023  润新知