ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

day10 权限颗粒度控制到按钮

2021-12-23 09:37:24  阅读:207  来源: 互联网

标签:__ permission url menu request day10 按钮 权限 permissions


修改表结构

rbac/models.py

from django.db import models


class Menu(models.Model):
    """
    菜单表
    """
    title = models.CharField(verbose_name='一级菜单名称', max_length=32)
    icon = models.CharField(verbose_name='图标', max_length=32, null=True, blank=True)

    def __str__(self):
        return self.title


class Permission(models.Model):
    """
    权限表
    """
    title = models.CharField(verbose_name='标题', max_length=32)
    url = models.CharField(verbose_name='含正则的URL', max_length=128)

    name = models.CharField(verbose_name='URL别名', max_length=32, null=True, unique=True)

    menu = models.ForeignKey(verbose_name='所属菜单', to='Menu', null=True, blank=True, help_text='null表示不是菜单;非null表示是二级菜单',on_delete=models.CASCADE)

    pid = models.ForeignKey(verbose_name='关联的权限', to='Permission', null=True, blank=True,related_name='parents',
                            help_text='对于非菜单权限需要选择一个可以成为菜单的权限,用户做默认展开和选中菜单',on_delete=models.CASCADE)

    def __str__(self):
        return self.title


class Role(models.Model):
    """
    角色
    """
    title = models.CharField(verbose_name='角色名称', max_length=32)
    permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True)

    def __str__(self):
        return self.title


class UserInfo(models.Model):
    """
    用户表
    """
    name = models.CharField(verbose_name='用户名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=64)
    email = models.CharField(verbose_name='邮箱', max_length=32)
    roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role', blank=True)

    def __str__(self):
        return self.name

表创建好之后新增字段值

权限初始化代码优化,将菜单权限返回制作成字典

rbac/service/init_Permission.py

# -*- encoding: utf-8 -*-
"""
@File    : init_Permission.py
@Time    : 2021-12-16 22:30
@Author  : tangsai
@Email   : 294168604@qq.com
@Software: PyCharm
"""
from django.conf import settings


def init_Permission(current_user, request):
    """
    用户权限的初始化
    :param current_user: 当前用户对象
    :param request: 请求相关所有数据
    :return:
    """
    # 2. 权限信息初始化
    # 根据当前用户信息获取此用户所拥有的所有权限,并放入session。
    # 当前用户所有权限
    permission_queryset = current_user.roles.filter(permissions__isnull=False).values("permissions__id",
                                                                                      "permissions__title",
                                                                                      "permissions__url",
                                                                                      "permissions__name",
                                                                                      "permissions__pid_id",
                                                                                      "permissions__pid__title",
                                                                                      "permissions__pid__url",
                                                                                      "permissions__menu_id",
                                                                                      "permissions__menu__title",
                                                                                      "permissions__menu__icon"
                                                                                      ).distinct()

    # 3. 获取权限+菜单信息
    permission_dict = {}

    menu_dict = {}

    for item in permission_queryset:

        permission_dict[item['permissions__name']] = {
            'id': item['permissions__id'],
            'title': item['permissions__title'],
            'url': item['permissions__url'],
            'pid': item['permissions__pid_id'],
            'p_title': item['permissions__pid__title'],
            'p_url': item['permissions__pid__url'],
        }

        menu_id = item['permissions__menu_id']
        if not menu_id:
            continue
        node = {'id': item['permissions__id'], 'title': item['permissions__title'], 'url': item['permissions__url']}

        if menu_id in menu_dict:
            menu_dict[menu_id]['children'].append(node)
        else:
            menu_dict[menu_id] = {
                'title': item['permissions__menu__title'],
                'icon': item['permissions__menu__icon'],
                'children': [node, ]
            }

    request.session[settings.PERMISSION_SESSION_KEY] = permission_dict
    request.session[settings.MENU_SESSION_KEY] = menu_dict

中间件代码修改,session返回是个字典需要兼容

rbac/middlewares/rbac.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
from django.conf import settings


class RbacMiddleware(MiddlewareMixin):
    """
    用户权限信息校验
    """

    def process_request(self, request):
        """
        当用户请求刚进入时候出发执行
        :param request:
        :return:
        """

        """
        1. 获取当前用户请求的URL
        2. 获取当前用户在session中保存的权限列表 ['/customer/list/','/customer/list/(?P<cid>\\d+)/']
        3. 权限信息匹配
        """
        current_url = request.path_info
        for valid_url in settings.VALID_URL_LIST:
            if re.match(valid_url, current_url):
                # 白名单中的URL无需权限验证即可访问
                return None

        permission_dict = request.session.get(settings.PERMISSION_SESSION_KEY)
        if not permission_dict:
            return HttpResponse('未获取到用户权限信息,请登录!')

        flag = False

        url_record = [
            {'title': '首页', 'url': '#'}
        ]

        for item in permission_dict.values():
            reg = "^%s$" % item['url']
            if re.match(reg, current_url):
                flag = True
                request.current_selected_permission = item['pid'] or item['id']
                if not item['pid']:
                    url_record.extend([{'title': item['title'], 'url': item['url'], 'class': 'active'}])
                else:
                    url_record.extend([
                        {'title': item['p_title'], 'url': item['p_url']},
                        {'title': item['title'], 'url': item['url'], 'class': 'active'},
                    ])
                request.breadcrumb = url_record
                print(request.breadcrumb)
                break

        if not flag:
            return HttpResponse('无权访问')

inclond_tag模板代码修改

rbac/templatetags/rbac.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.template import Library
from django.conf import settings
from collections import OrderedDict
import re

register = Library()


@register.inclusion_tag('rbac/static_menu.html')
def static_menu(request):
    """
    创建一级菜单
    :return:
    """
    menu_list = request.session[settings.MENU_SESSION_KEY]
    return {'menu_list': menu_list}


@register.inclusion_tag('rbac/multi_menu.html')
def multi_menu(request):
    """
    创建二级菜单
    :return:
    """
    menu_dict = request.session[settings.MENU_SESSION_KEY]

    # 对字典的key进行排序
    key_list = sorted(menu_dict)

    # 空的有序字典
    ordered_dict = OrderedDict()

    for key in key_list:
        val = menu_dict[key]
        val['class'] = 'hide'

        for per in val['children']:
            if per['id'] == request.current_selected_permission:
                per['class'] = 'active'
                val['class'] = ''
        ordered_dict[key] = val

    return {'menu_dict': ordered_dict}


@register.inclusion_tag('rbac/breadcrumb.html')
def breadcrumb(request):
    return {'record_list': request.breadcrumb}


@register.filter
def has_permission(request, name):
    """
    判断是否有权限
    :param request:
    :param name:
    :return:
    """
    if name in request.session[settings.PERMISSION_SESSION_KEY]:
        return True

模板修改:
customer_list.html

{% extends 'layout.html' %}
{% load rbac %}

{% block content %}

    <div class="luffy-container">
        <div class="btn-group" style="margin: 5px 0">
            {% if request|has_permission:"customer_add" %}
                <a class="btn btn-default" href="/customer/add/">
                    <i class="fa fa-plus-square" aria-hidden="true"></i> 添加客户
                </a>
            {% endif %}

            {% if request|has_permission:"customer_import" %}
                <a class="btn btn-default" href="/customer/import/">
                    <i class="fa fa-file-excel-o" aria-hidden="true"></i> 批量导入
                </a>
            {% endif %}
        </div>
        <table class="table table-bordered table-hover">
            <thead>
            <tr>
                <th>ID</th>
                <th>客户姓名</th>
                <th>年龄</th>
                <th>邮箱</th>
                <th>公司</th>
                {% if request|has_permission:"customer_del" or request|has_permission:"customer_edit" %}
                    <th>选项</th>
                {% endif %}
            </tr>
            </thead>
            <tbody>
            {% for row in data_list %}
                <tr>
                    <td>{{ row.id }}</td>
                    <td>{{ row.name }}</td>
                    <td>{{ row.age }}</td>
                    <td>{{ row.email }}</td>
                    <td>{{ row.company }}</td>
                    {% if request|has_permission:"customer_del" or request|has_permission:"customer_edit" %}
                        <td>
                            {% if request|has_permission:"customer_edit" %}
                                <a style="color: #333333;" href="/customer/edit/{{ row.id }}/">
                                    <i class="fa fa-edit" aria-hidden="true"></i></a>
                            {% endif %}
                            {% if request|has_permission:"customer_del" %}
                                <a style="color: #d9534f;" href="/customer/del/{{ row.id }}/"><i
                                        class="fa fa-trash-o"></i></a>
                            {% endif %}
                        </td>
                    {% endif %}

                </tr>
            {% endfor %}
            </tbody>
        </table>
    </div>
{% endblock %}

payment_list.html

{% extends 'layout.html' %}
{% load rbac %}
{% block content %}

    <div class="luffy-container">
        {% if request|has_permission:"payment_add" %}
            <div style="margin: 5px 0;">
                <a class="btn btn-success" href="/payment/add/">
                    <i class="fa fa-plus-square" aria-hidden="true"></i> 添加缴费记录
                </a>
            </div>
        {% endif %}
        <table class="table table-bordered table-hover">
            <thead>
            <tr>
                <th>ID</th>
                <th>客户姓名</th>
                <th>金额</th>
                <th>付费时间</th>

                {% if request|has_permission:"payment_del" or request|has_permission:"payment_edit" %}
                    <th>选项</th>
                {% endif %}
            </tr>
            </thead>
            <tbody>
            {% for row in data_list %}
                <tr>
                    <td>{{ row.id }}</td>
                    <td>{{ row.customer.name }}</td>
                    <td>{{ row.money }}</td>
                    <td>{{ row.create_time|date:"Y-m-d H:i:s" }}</td>
                    {% if request|has_permission:"payment_del" or request|has_permission:"payment_edit" %}
                        <td>
                            {% if request|has_permission:"payment_edit" %}
                                <a style="color: #333333;" href="/payment/edit/{{ row.id }}/">
                                    <i class="fa fa-edit" aria-hidden="true"></i></a>
                            {% endif %}
                            {% if request|has_permission:"payment_del" %}
                                <a style="color: #d9534f;" href="/payment/del/{{ row.id }}/"><i
                                        class="fa fa-trash-o"></i></a>
                            {% endif %}
                        </td>
                    {% endif %}

                </tr>
            {% endfor %}
            </tbody>
        </table>
    </div>
{% endblock %}

标签:__,permission,url,menu,request,day10,按钮,权限,permissions
来源: https://www.cnblogs.com/simon1993/p/15722023.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有