权限组件(12):自动发现项目中有别名的URL

自动发现项目中所有有别名的URL,效果如下:

customer_list {‘name‘: ‘customer_list‘, ‘url‘: ‘/customer/list/‘}
customer_add {‘name‘: ‘customer_add‘, ‘url‘: ‘/customer/add/‘}
customer_edit {‘name‘: ‘customer_edit‘, ‘url‘: ‘/customer/edit/(?P<cid>\\d+)/‘}
customer_del {‘name‘: ‘customer_del‘, ‘url‘: ‘/customer/del/(?P<cid>\\d+)/‘}
customer_import {‘name‘: ‘customer_import‘, ‘url‘: ‘/customer/import/‘}
customer_tpl {‘name‘: ‘customer_tpl‘, ‘url‘: ‘/customer/tpl/‘}
payment_list {‘name‘: ‘payment_list‘, ‘url‘: ‘/payment/list/‘}
payment_add {‘name‘: ‘payment_add‘, ‘url‘: ‘/payment/add/‘}
payment_edit {‘name‘: ‘payment_edit‘, ‘url‘: ‘/payment/edit/(?P<pid>\\d+)/‘}
payment_del {‘name‘: ‘payment_del‘, ‘url‘: ‘/payment/del/(?P<pid>\\d+)/‘}
rbac:role_list {‘name‘: ‘rbac:role_list‘, ‘url‘: ‘/rbac/role/list/‘}
rbac:role_add {‘name‘: ‘rbac:role_add‘, ‘url‘: ‘/rbac/role/add/‘}
rbac:role_edit {‘name‘: ‘rbac:role_edit‘, ‘url‘: ‘/rbac/role/edit/(?P<pk>\\d+)/‘}
rbac:role_del {‘name‘: ‘rbac:role_del‘, ‘url‘: ‘/rbac/role/del/(?P<pk>\\d+)/‘}
rbac:user_list {‘name‘: ‘rbac:user_list‘, ‘url‘: ‘/rbac/user/list/‘}
rbac:user_add {‘name‘: ‘rbac:user_add‘, ‘url‘: ‘/rbac/user/add/‘}
rbac:user_edit {‘name‘: ‘rbac:user_edit‘, ‘url‘: ‘/rbac/user/edit/(?P<pk>\\d+)/‘}
rbac:user_del {‘name‘: ‘rbac:user_del‘, ‘url‘: ‘/rbac/user/del/(?P<pk>\\d+)/‘}
rbac:user_reset_pwd {‘name‘: ‘rbac:user_reset_pwd‘, ‘url‘: ‘/rbac/user/reset/password/(?P<pk>\\d+)/‘}
rbac:menu_list {‘name‘: ‘rbac:menu_list‘, ‘url‘: ‘/rbac/menu/list/‘}
rbac:menu_add {‘name‘: ‘rbac:menu_add‘, ‘url‘: ‘/rbac/menu/add/‘}
rbac:menu_edit {‘name‘: ‘rbac:menu_edit‘, ‘url‘: ‘/rbac/menu/edit/(?P<pk>\\d+)‘}
rbac:menu_del {‘name‘: ‘rbac:menu_del‘, ‘url‘: ‘/rbac/menu/del/(?P<pk>\\d+)‘}
rbac:second_menu_add {‘name‘: ‘rbac:second_menu_add‘, ‘url‘: ‘/rbac/second/menu/add/(?P<menu_id>\\d+)/‘}
rbac:second_menu_edit {‘name‘: ‘rbac:second_menu_edit‘, ‘url‘: ‘/rbac/second/menu/edit/(?P<pk>\\d+)/‘}
rbac:second_menu_del {‘name‘: ‘rbac:second_menu_del‘, ‘url‘: ‘/rbac/second/menu/del/(?P<pk>\\d+)/‘}
rbac:permission_add {‘name‘: ‘rbac:permission_add‘, ‘url‘: ‘/rbac/permission/add/(?P<second_menu_id>\\d+)/‘}
rbac:permission_edit {‘name‘: ‘rbac:permission_edit‘, ‘url‘: ‘/rbac/permission/edit/(?P<pk>\\d+)/‘}
rbac:permission_del {‘name‘: ‘rbac:permission_del‘, ‘url‘: ‘/rbac/permission/del/(?P<pk>\\d+)/‘}
rbac:multi_permissions {‘name‘: ‘rbac:multi_permissions‘, ‘url‘: ‘/rbac/multi/permissions/‘}

一、配置路由

rbac/urls.py

from django.urls import re_path

...
from rbac.views import menu
...
urlpatterns = [
    ...
    # 批量操作权限
    re_path(r‘^multi/permissions/$‘, menu.multi_permissions, name=‘multi_permissions‘)  # 自动发现项目中的所有URL
    ...
]

二、自动发现URL功能实现

排除不用发现的URL

settings.py

...
AUTO_DISCOVER_EXCLUDE = [
    ‘/admin/‘,
    ‘/login/‘,
]
...

rbac/service/router.py

import re

from collections import OrderedDict

from django.conf import settings
from django.utils.module_loading import import_string  # 根据字符串的形式,帮我们去导入模块
from django.urls import URLPattern, URLResolver  # 路由分发:URLResolver。非路由分发:URLPattern

def check_url_exclude(url):
    """
    排除一些特定的url
    :param url:
    :return:
    """
    for regex in settings.AUTO_DISCOVER_EXCLUDE:
        if re.match(regex, url):
            return True

def recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict):
    """
    :param pre_namespace: namespace前缀(rbac:xxx),以后用于拼接name
    :param per_url: url的前缀(rbac/xxx),以后用于拼接url
    :param urlpatterns: 路由关系列表
    :param url_ordered_dict: 用于保存递归中获取的所有路由
    :return:
    """

    # 路由分发:URLResolver。非路由分发:URLPattern
    for item in urlpatterns:
        if isinstance(item, URLPattern):  # 非路由分发,将路由添加到url_ordered_dict
            if not item.name:  # url中反向命名的name,没有的话不做处理,直接跳过。
                continue
            if pre_namespace:  # 如果有命名空间就进行拼接。示例:rbac:role_list
                name = f‘{pre_namespace}:{item.name}‘
            else:
                name = item.name  # 示例:role_list

            # 判断url有没有前缀,如果有前缀的话我们要给它拼接上,一般url都是有前缀的,因为从根级路由开始我们就加了个/
            url = pre_url + item.pattern.regex.pattern  # pattern.regex.pattern是拿到当前url django 1.X里是 url._regex
            # 拼接完长这样:/^rbac/^user/edit/(?P<pk>\d_+)/$
            url = url.replace(‘^‘, ‘‘).replace(‘$‘, ‘‘)  # 把起始符和终止符替换成空的,最后得到:/rbac/user/edit/(?P<pk>\d_+)/

            if check_url_exclude(url):  # 判断是否admin、login等我们不需要的url,是的话直接跳过
                continue

            url_ordered_dict[name] = {‘name‘: name, ‘url‘: url}
            # ‘rbac:menu_list‘:{name:‘rbac:menu_list‘,url:‘xxxxx/yyyy/menu/list‘}

        elif isinstance(item, URLResolver):  # 路由分发,进行递归操作
            if pre_namespace:
                """
                # 有前缀  示例:admin 。admin.site.urls的urls的返回值是:
                @property
                def urls(self):
                    return self.get_urls(), ‘admin‘, self.name。 返回值的第二个是命名空间
                """
                if item.namespace:  # 如果有自己的namespace比如说user_list,和前面的pre_namespace进行拼接,结果是rbac:user_list
                    namespace = f"{pre_namespace}:{item.namespace}"
                else:
                    """
                    自己没有namespace,但是父级有,那么namespace就应该是父级的,所以那就直接应该是rbac。
                    示例:re_path(r‘^role/list/$‘, include(‘xxx.urls‘))。rbac里的一条路由又进行路由分发,但是自己没有命名空间
                    """
                    namespace = item.namespace  # 写成namespace = pre_namespace也可以
            else:
                if item.namespace:  # 父级没有namespace,自己有。示例:re_path(r‘^rbac/‘, include((‘rbac.urls‘, ‘rbac‘)), )
                    namespace = item.namespace
                else:  # 父级没有namespace,自己也没有
                    namespace = None

            recursion_urls(namespace, pre_url + item.pattern.regex.pattern, item.url_patterns, url_ordered_dict)

            """
            pre_url(上一级的url) + item.pattern.regex.pattern(当前路由分发的前缀),item.url_patterns(当前路由分发的urlpatterns)
            拿re_path(r‘^rbac/‘, include((‘rbac.urls‘, ‘rbac‘)))举例:
            namespace = rbac,  pre_url=/,  item.pattern.regex.pattern=^rbac/,item.url_patterns = rbac.urls下的所有url
            在django1.x里item.pattern.regex.pattern要换成item.regex.pattern
            """

def get_all_url_dict():
    """
    获取项目中所有的URL(必须有name别名)
    :return:
    """

    url_ordered_dict = OrderedDict()

    all_url = import_string(settings.ROOT_URLCONF)  # from permission_learn import urls

    recursion_urls(None, ‘/‘, all_url.urlpatterns, url_ordered_dict)  # 递归的去获取所有的路由。根目录没有namespace,根路由用/

    # 得到类似这样的结果:
    """
    {
        ‘rbac:menu_list‘:{name:‘rbac:menu_list‘,url:‘xxxxx/yyyy/menu/list‘}
    }
    """

    return url_ordered_dict

  

三、在视图函数引用

rbac/views/menu.py

...
from rbac.service.router import get_all_url_dict
...

...
def multi_permissions(request):
    """
    批量操作权限
    :param request:
    :return:
    """

    # 获取项目中所有的url

    all_url_dict = get_all_url_dict()
    for k, v in all_url_dict.items():
        print(k, v)

    return HttpResponse(‘ok it‘)
...

以后我们需要在页面展示这些URL,并对其进行增删改和权限操作

原文地址:https://www.cnblogs.com/lshedward/p/10518270.html

时间: 2024-10-24 19:12:01

权限组件(12):自动发现项目中有别名的URL的相关文章

自动发现项目中的URL,django1版本和django2版本

一.django 1 版本 routers.py import re from collections import OrderedDict from django.conf import settings from django.utils.module_loading import import_string # 根据字符串的形式,帮我们去导入模块 from django.urls import RegexURLResolver, RegexURLPattern # 路由分发:URLReso

将权限组件应用到新项目

1. 拷贝rbac组件到新的项目中,注册app 2. 修改用户表,继承rbac中的User class User(models.Model): """ 用户表 """ # name = models.CharField(max_length=32, verbose_name='名称') # password = models.CharField(max_length=32, verbose_name='密码') roles = models.Ma

Django自动获取项目中的全部URL

from django.utils.module_loading import import_string from django.conf import settings # for django 1.0 # from django.urls import RegexURLResolver, RegexURLPattern # for django 2.0 from django.urls.resolvers import URLResolver, URLPattern def recursi

zabbix的自动发现、自定义添加监控项目

1.zabbix的自动发现这里的自动发现,所显示出来的是规则的上自动了现 然后 可以对其内容进行相关的配制,如时间或周期 注意:对于单个主机的规则,可以自行添加或删除, 但对于已经添加好了的规则,若需要修改那么,就只有到模板里面进行相关设置.   2.自定义添加监控项目,监控项目都是针对于客户机而言的,一般都是对客户机进行配制 先在客户机创建一个脚本加入以下内容:mkdir /etc/zabbix/sh; vim /etc/zabbix/sh/estab.sh #!/bin/bash##获取80

drf框架 8 系统权限类使用 用户中心信息自查 token刷新机制 认证组件项目使用:多方式登录 权限组件项目使用:vip用户权限 频率组件 异常组件项目使用

系统权限类使用 图书接口:游客只读,用户可增删改查权限使用 from rest_framework.permissions import IsAuthenticatedOrReadOnly class BookViewSet(ModelViewSet): # 游客只读,用户可增删改查 permission_classes = [IsAuthenticatedOrReadOnly] queryset = models.Book.objects.all() serializer_class = se

Docker集群实验环境布署--swarm【3 注册服务监控与自动发现组件--consul】

参考官网集群配置方式 https://hub.docker.com/r/progrium/consul/ 集群中需要manager与node能通信consul的发现服务,不然,管理节点选举不了,无法执行docker 命令. 集群中consul工作3台的机器,大于等2台时,集群仍正常工作,如果,发生只有1台时,集群失效,无法选择管理节点,需要启动数据再次达到3台的标准后,集群才能慢慢恢复. 测试最终得出一个惊人结论,我把consul集群删除后,重新拉起时,元数据全部自动发现恢复. 10.40.10

zabbix自动发现oracle表空间并监控其使用率

监控需求 Oracle表空间使用率实时监控,当表空间使用率达到95%时触发告警机制.Oracle表空间分为系统默认表空间和用户创建的表空间,而表空间又有自动扩展和非自动扩展两种类型,用户(DBA)在创建表空间时可以根据应用需求指定是否开启表空间自动扩展.那么在这里我们需要分析一个监控策略,就是当zabbix监控到某个表空间使用率达到95%,那么就让触发器触发警告(Warning)信息,并发送邮件给DBA或管理者.当检测到表空间没有开启自动扩展时,则触发Information信息.说明一下:ora

12天OA项目

OA(Office Automation):办公自动化--辅助管理,提高办公效率的系统. OA的功能: 文字处理,申请审批,办公用品管理,公文管理,会议管理,资料管理,知识管理,电子邮件等... 根据用户实际需求确定实际项目的功能. BBS--论坛 CRM--客户关系管理系统 CMS--内容管理系统 1.软件开发的简单步骤: <1.需求分析 <2.分析设计 <3.编码实现 <4.测试验证(修改) <5.部署与后期维护 2.每个步骤具体要做什么,谁来做? 3.我们要做什么? 设

权限组件之录入数据

权限组件之录入数据 1.新建一个django项目 rbac 2.增加一个app应用 3.什么是rbac??? 生成表 4.3张表一写,会生成5张表 5.数据库迁移 6.查看表,没有我们自己写的表???都是自带的表 7.settings配置 8.入口文件 9.重新数据化迁移,查看表 admin  添加数据 10.添加数据   admin 11.创建管理员,用户名.(邮箱可以不用填写).密码 12.登入admin 13.默认没有我们自己写的app里的表,需要注册才会显示表 14.第三张表不用加. 1