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')

    # 保存为用户分配的角色,这里需要注意,set方法是先清空后绑定
    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表一对一关联;

      需要注意的是这里是跨app关联,所以需要先引入另一个APP的User表

      user=models.OneToOneField(user,null=True,on_delete=models.CASCADE)

(4) 数据迁移;

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

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django中,可以使用权限系统来控制用户对不同页面的访问权限权限系统基于用户和用户组的概念来进行权限管理。 首先,需要在数据库中创建权限记录。可以使用Django提供的`manage.py`命令来创建权限记录,也可以在Django Admin后台手动创建。例如,可以创建一个名为"访问页面A"的权限记录。 接下来,可以在视图函数或类中使用`@permission_required`装饰器来限制页面的访问权限。通过该装饰器,只有拥有特定权限的用户才能访问被装饰的视图。例如,可以在视图函数中加上`@permission_required('app_name.访问页面A')`。 此外,还可以在模板文件中使用`{% if user.has_perm %}`来判断用户是否拥有特定权限,从而动态展示页面上的内容。例如,可以在模板中使用`{% if user.has_perm 'app_name.访问页面A' %} 显示页面A的内容 {% endif %}`。 如果要限制整个应用中的所有视图都需要特定权限才能访问,可以在项目的URL配置中使用`login_required`装饰器和`PermissionRequiredMixin`类。例如,可以在`urls.py`文件中对整个应用添加如下代码: ``` from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import PermissionRequiredMixin urlpatterns = [ path('app_name/', login_required(PermissionRequiredMixin.as_view( permission_required='app_name.访问页面A')), name='app_name'), # ... ] ``` 以上是使用Django权限系统来控制不同页面的访问权限的基本方法。通过创建权限记录、使用装饰器和在模板中判断权限,可以实现在不同页面中控制用户的访问权限

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值