Django3.2 自动发现所有路由代码详解

目录
  • 1.需求
  • 2.代码实现
  • 总结

1.需求

发现项目本地所有带别名的URL,组成一个有序字典,方便后续调用;
定向排除部分URL,如Django自带的 admin下的路由;

2.代码实现

import re              # 正则
from collections import OrderedDict      # 创建有序字典
from django.conf import settings          # 导入setting配置文件(获取项目根路径urls.py)
from django.utils.module_loading import import_string      # 字符串导入模块
from django.urls import URLPattern, URLResolver            # Django自定义的类,可以判断当前URL是否为根路径(URLPattern)或继续向下分发(URLResolver )

def check_url_exclude(url):
    """
    排除一些特定的URL
    :param url: 待检验的URL
    :return:
    """
    for regex in settings.AUTO_DISCOVER_EXCLUDE:     #将要定向排除的URL(可包含正则) 按照列表的形式写入配置文件 settings.AUTO_DISCOVER_EXCLUDE  下
        if re.match(regex, url):
            return True
"""
示例:
AUTO_DISCOVER_EXCLUDE = [
    '/admin/.*',
    '/login/',
    '/logout/',
    '/index/',
]
"""
def recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict):
    """
    递归的去获取URL
    :param pre_namespace: namespace前缀,用于拼接name
    :param pre_url: url前缀,用于拼接url
    :param urlpatterns: 路由关系列表
    :param url_ordered_dict: 用于保存递归中获取的所有路由
    :return:
    """
    for item in urlpatterns:
        if isinstance(item, URLPattern):  # 已经是根网址,获取name及url写入url_ordered_dict
            if not item.name:  # 没有别名(name)的路由地址直接跳过
                continue
            # 拼接路由别名(包含分发下来的namespace;如 "rbac:menu_list")
            if pre_namespace:
                name = "%s:%s" % (pre_namespace, item.name)
            else:
                name = item.name
            # 拼接路由地址URl(包含分发下来的上层路由;如 "/rbac/menu/list")
            url = pre_url + item.pattern.regex.pattern        # 此时拼接的路由包含起止符号,如:/^rbac/^menu/list/$
            url = url.replace("^", "").replace("$", "")           # 删除起止符:/rbac/menu/list/
            # 排除一些特定的路由URL
            if check_url_exclude(url):                             # 调用check_url_exclude函数定向排除部分URL
                continue
            url_ordered_dict[name] = {"name": name, "url": url}

        elif isinstance(item, URLResolver):  # 路由分发,递归操作
            if pre_namespace:                                                                              # 上次循环(上一层)分发是否包含namespace
                if item.namespace:                                                                         # 本次循环(当前层)是否包含namespace
                    namespace = "%s:%s" % (pre_namespace, item.namespace,)         # 上层、当前层都包含直接拼接两层的namespace
                else:
                    namespace = pre_namespace                                                      # 当前层分发不包含namespace,直接用上一层的
            else:
                if item.namespace:
                    namespace = item.namespace                                                     # 上一层分发不包含namespace,直接使用当前层的
                else:
                    namespace = None                                                                     # 上一层、当前层都没有,直接定义层none
            recursion_urls(namespace, pre_url + item.pattern.regex.pattern, item.url_patterns, url_ordered_dict)       # 递归继续执行
def get_all_url_dict():
    """
    获取项目所有路由
    :return:
    """
    url_ordered_dict = OrderedDict()                                        # 包含本项目所有权限URl的有序字典
    md = import_string(settings.ROOT_URLCONF)                    # 配置文件内的 ROOT_URLCONF 为本项目根路由urls.py 的路径(字符串),使用 import_string 用字符串加载模块
    recursion_urls(None, "/", md.urlpatterns, url_ordered_dict)    # 调用 recursion_urls 函数获取所有路由字典,根路径下没有namespace 定义为 None;没有url前缀 定义为 /
    return url_ordered_dict

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Django 路由系统URLconf的使用

    URLconf是什么? URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的view函数之间的映射表:你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码. urlpatterns = [ url(正则表达式, views视图函数,参数,别名), re_path(正则表达式, views视图函数,参数,别名), (在2.0以上版本中使用re_path), ] 参数说明: 正则表达式(regex): regex是正

  • Django 路由层URLconf的实现

    分组 分组的目的:让服务端获得url中的具体数据,通过分组,把需要的数据按函数传参的方式传递给服务器后台 1-无名分组 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号 # app01/urls.py from django.urls import path, re_path from app01 import views app_name = "app01" urlpatterns = [ path("login/", views.login, name=

  • Django实现自定义路由转换器

    自定义路径转换器 有时候上面的内置的url转换器并不能满足我们的需求,因此django给我们提供了一个接口可以让我们自己定义自己的url转换器 django内置的路径转换器源码解析 在我们自定义路由转换器之前,我们先查看一下django内置的那些路由转换器怎么写的,源码路径from django.urls import converters class IntConverter: regex = '[0-9]+' def to_python(self, value): return int(va

  • Django 路由控制的实现

    一 Django中路由的作用 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行 典型的例子: from django.urls import path urlpatterns = [ path('articles', views.special), ] articles这个路由对应着视图函数中special这个方法,浏览器输入这个链接,就

  • Django 路由控制的实现代码

    一.URL路由基础 URL是web服务的路口,用户通过浏览器发送过来的任何请求都会被发送到一个指定的URL地址里,然后被响应. 在django项目中编写路由就是向外暴露我们接收哪些URL的请求,除此之外任何的URL都不会被处理,URL路由就是web服务对外暴露的API 二.Django处理请求 确定要使用的 URLconf 模块,通常是settings中 ROOT_URLCONF 设置的值,如果传入的 HttpRequest 对象具有 urlconf 属性(中间件设置),则使用其值代替setti

  • Django框架的使用教程路由请求响应的方法

    路由 路由可以定义在工程的目录下(看你的需求),也可以定义在各个应用中来保存应用的路由,用主路文件urls中使用include()包含各个应用的子路由的数据 路由的解析顺序 Django接收到请求后,从主路由文件urlpatterns中的路由从上倒下顺序查找,如果有include包含,则进入子应用的urls中的urlpatterns中查找(从上而下) 路由的结尾斜线 Django有/结尾路由,用户不需要加/,就可以直接重定向到/结尾的路径上 路由命名(可以避免不同应用使用相同名字发生冲突) 如:

  • Django3.2 自动发现所有路由代码详解

    目录 1.需求 2.代码实现 总结 1.需求 发现项目本地所有带别名的URL,组成一个有序字典,方便后续调用: 定向排除部分URL,如Django自带的 admin下的路由: 2.代码实现 import re # 正则 from collections import OrderedDict # 创建有序字典 from django.conf import settings # 导入setting配置文件(获取项目根路径urls.py) from django.utils.module_loadi

  • Python图片批量自动抠图去背景的代码详解

    今天发现个好东西啊,叫片刻抠图,是一个在线对图片自动抠图去除背景的网站.只要上传图片,就可以自动把背景去掉把目标对象抠出来. 不管是动物.汽车或各种产品,还是人物,都可以全自动做到令人惊艳的抠图效果!而且还说可以做到发丝级 AI 自动抠图,作为一个头发存留不多的程序员,突然莫名感觉到一丝来自这个世界的恶意. 这个抠图有什么用?比如可以把人物抠出来换个背景: 也可以把产品抠出来做成新的商品宣传图:(做电商的朋友肯定懂) 这么好用的东西,现在最关键的是:完全免费! emmmmmm,这个消息被我的几十

  • Android实现图片自动切换功能(实例代码详解)

    在Android中图片的自动切换不仅可以实现自动切换,而且还可以使用手动切换.而且一般在切换的时候,在图片下方还带有其他内容的切换,用来标记是第几个图片的切换. 这种效果在我们日常生活中很常见,例如某宝购物,一些商城都可以使用到,用户体验度极好,今天小编就通过实例代码给大家分享android 图片自动切换功能的实现. 实现效果如下: 具体的示例代码如下: 布局代码: <?xml version="1.0" encoding="utf-8"?> <S

  • Spring自动装配与扫描注解代码详解

    1 javabean的自动装配 自动注入,减少xml文件的配置信息. <?xml version="1.0" encoding="UTF-8"?> <!-- 到入xml文件的约束 --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p&quo

  • Vue中的组件及路由使用实例代码详解

    1.组件是什么 组件系统是 Vue 的一个重要概念,因为它是一种抽象,允许我们使用小型.独立和通常可复用的组件构建大型应用.通常一个应用会以一棵嵌套的组件树的形式来组织: 1.1组件的声明及使用 全局组件 <body> <div id="app"> <!-- 用全局组件的名称作为HTML的标签 --> <myzujian></myzujian> </div> </body> <script>

  • java多线程中断代码详解

    一.java中终止线程主要有三种方法: ①线程正常退出,即run()方法执行完毕了 ②使用Thread类中的stop()(已过期不推荐使用)方法强行终止线程. ③使用中断机制 t.stop()调用时,终止线程,会导致该线程所持有的锁被强制释放,从而被其他线程所持有,因此有可能导致与预期结果不一致.下面使用中断信号量中断非阻塞状态的线程中: public class TestStopThread { public static void main(String[] args) throws Int

  • Java语言中的内存泄露代码详解

    Java的一个重要特性就是通过垃圾收集器(GC)自动管理内存的回收,而不需要程序员自己来释放内存.理论上Java中所有不会再被利用的对象所占用的内存,都可以被GC回收,但是Java也存在内存泄露,但它的表现与C++不同. JAVA中的内存管理 要了解Java中的内存泄露,首先就得知道Java中的内存是如何管理的. 在Java程序中,我们通常使用new为对象分配内存,而这些内存空间都在堆(Heap)上. 下面看一个示例: public class Simple { public static vo

  • Hibernate中Session增删改查操作代码详解

    把三状态转换图放在这,方便分析方法的作用: 1.Session的save()方法 Session是Hibernate所有接口中最重要的接口,提供了对数据保存,更新,查询和删除的方法. Session的save()方法可以使临时态或游离态转换为持久态.例如,保存一个Customer对象: SessionFactory sessionFactory; Configuration configuration = new Configuration().configure(); sessionFacto

  • Python中协程用法代码详解

    本文研究的主要是python中协程的相关问题,具体介绍如下. Num01–>协程的定义 协程,又称微线程,纤程.英文名Coroutine. 首先我们得知道协程是啥?协程其实可以认为是比线程更小的执行单元. 为啥说他是一个执行单元,因为他自带CPU上下文.这样只要在合适的时机, 我们可以把一个协程 切换到另一个协程. 只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的. Num02–>协程和线程的差异 那么这个过程看起来和线程差不多.其实不然, 线程切换从系统层面远不止保存和恢复 CP

  • Hibernate初体验及简单错误排除代码详解

    Hibernate是什么,有多少好处,想必查找这类博文的都知道,所以就不多说了.下面是我对Hibernate简单使用的一个小小的总结.与君(主要是刚入门的)共勉吧! 创建的顺序 创建Hibernate的配置文件 创建持久化的类 创建对象-关系的映射文件 通过HibernateAPI编写访问数据库的代码 关于详细的步骤 导入Hibernate必须的jar包(hibernate-release-版本号.Final\lib\required) 然后是导入MySQL的jdbc的驱动(mysql-conn

随机推荐