zoukankan      html  css  js  c++  java
  • 自动发现项目中的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 # 路由分发:URLResolver。不是路由分发:URLPattern
    
    
    def check_url_exclude(url):
        """
        排除一些特定的url
        :param url:
        :return:
        """
        exclude_url = [
            '/admin.*',
            '/login/'
        ]
        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:......),以后用于拼接name
        :param pre_url: url的前缀(rbac/......),以后用于拼接url
        :param urlpatterns: 路由关系列表
        :param url_ordered_dict: 用于保存递归中获取的所有路由
        :return:
        """
        for item in urlpatterns:
            if isinstance(item,RegexURLPatter):  # 非路由分发,将路由添加到url_ordered_dict
                if not item.name:  # url中反向命名的name
                    continue
                if pre_namespace:
                    name = f"{pre_namespace}:{item.name}"
                else:
                    name = item.name
                url = pre_url + item._regex  # /^rbac/^user/edit/(?P<pk>d_+)/$
                url = url.replace('^', '').replace('$', '')  # /rbac/user/edit/(?P<pk>d_+)/
    
                if check_url_exclude(url):
                    continue
                url_ordered_dict[name] = {'name': name, 'url': url}
    
            elif isinstance(item,  RegexURLResolver):  # 路由分发,进行递归操作
                if pre_namespace:
                    if item.namespace:
                        namespace = f"{pre_namespace}:{item.namespace}"
                    else:
                        namespace = item.namespace
                else:
                    if item.namespace:
                        namespace = item.namespace
                    else:
                        namespace = None
                recursion_urls(namespace, pre_url + item.regex.pattern, item.url_patterns, url_ordered_dict)
    
    
    def get_all_url_dict():
        """
        获取项目中所有的URL(必须有name别名)
        :return:
        """
        url_ordered_dict = OrderedDict()
        """
        {
            'rbac:menu_list':{name:'rbac:menu_list',url:'xxxxx/yyyy/menu/list'}
        }
        """
    
        md = import_string(settings.ROOT_URLCONF)  # from permision_learn import urls
    
        recursion_urls(None, '/', md.urlpatterns, url_ordered_dict)  # 递归的去获取所有的路由。根目录没有namespace,根路由用/
    
        return url_ordered_dict

    views.py

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

    二、django 2版本

    django 2版本有些坑,和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 URLPattern, URLResolver  # 路由分发:URLResolver。不是路由分发:URLPattern
    
    
    def check_url_exclude(url):
        """
        排除一些特定的url
        :param url:
        :return:
        """
        exclude_url = [
            '/admin.*',
            '/login/'
        ]
        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:......),以后用于拼接name
        :param pre_url: url的前缀(rbac/......),以后用于拼接url
        :param urlpatterns: 路由关系列表
        :param url_ordered_dict: 用于保存递归中获取的所有路由
        :return:
        """
        for item in urlpatterns:
            if isinstance(item, URLPattern):  # 非路由分发,将路由添加到url_ordered_dict
                if not item.name:  # url中反向命名的name
                    continue
                if pre_namespace:
                    name = f"{pre_namespace}:{item.name}"
                else:
                    name = item.name
                url = pre_url + item.pattern.regex.pattern  # /^rbac/^user/edit/(?P<pk>d_+)/$
                url = url.replace('^', '').replace('$', '')  # /rbac/user/edit/(?P<pk>d_+)/
    
                if check_url_exclude(url):
                    continue
                url_ordered_dict[name] = {'name': name, 'url': url}
    
            elif isinstance(item, URLResolver):  # 路由分发,进行递归操作
                if pre_namespace:
                    if item.namespace:
                        namespace = f"{pre_namespace}:{item.namespace}"
                    else:
                        namespace = item.namespace
                else:
                    if item.namespace:
                        namespace = item.namespace
                    else:
                        namespace = None
                recursion_urls(namespace, pre_url + item.pattern.regex.pattern, item.url_patterns, url_ordered_dict)
    
    
    def get_all_url_dict():
        """
        获取项目中所有的URL(必须有name别名)
        :return:
        """
        url_ordered_dict = OrderedDict()
        """
        {
            'rbac:menu_list':{name:'rbac:menu_list',url:'xxxxx/yyyy/menu/list'}
        }
        """
    
        md = import_string(settings.ROOT_URLCONF)  # from permision_learn import urls
    
        recursion_urls(None, '/', md.urlpatterns, url_ordered_dict)  # 递归的去获取所有的路由。根目录没有namespace,根路由用/
    
        return url_ordered_dict

    views.py

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

  • 相关阅读:
    linux系列之-—03 压缩和解压缩命令
    Atlassian Confluence安装
    常见ODBC及OLEDB连接串的写法
    windows 怎么验证域名是否开启了 https
    Jenkins基础篇 系列之-—05 集成JIRA
    SVN系列之—-SVN版本回滚的办法
    JMeter 系列之—-02 创建数据库测试计划
    golang web框架 beego 学习 (一) 环境搭建
    补充 3:Golang 一些特性
    补充 1: panic 、recover、 defer
  • 原文地址:https://www.cnblogs.com/lshedward/p/10467931.html
Copyright © 2011-2022 走看看