You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django应用中生成使用caching_func的端点列表?

Django 追踪调用特定函数的API端点方法

要在Django启动时收集所有内部调用caching_func的API端点并生成完整URL路径,可按以下步骤实现:

1. 静态检测视图方法是否调用目标函数

通过解析函数的抽象语法树(AST),静态检测视图方法内部是否直接调用了caching_func,无需运行时执行业务逻辑:

import ast
import inspect

def uses_caching_func(func):
    """检测函数是否直接调用了caching_func"""
    # 获取函数源码并解析为AST
    try:
        tree = ast.parse(inspect.getsource(func))
    except TypeError:
        # 处理无法获取源码的情况(如内置函数)
        return False
    
    for node in ast.walk(tree):
        # 检测直接调用:caching_func(...)
        if isinstance(node, ast.Call) and isinstance(node.func, ast.Name):
            if node.func.id == "caching_func":
                return True
        # 检测别名/属性调用:如from .utils import caching_func as cf 或 obj.caching_func(...)
        elif isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute):
            if node.func.attr == "caching_func":
                return True
    return False

2. 遍历路由与ViewSet,生成完整端点URL

Django启动后,遍历所有已注册的路由,匹配ViewSet中的@action方法,结合检测结果生成完整URL:

from django.urls import get_resolver
from rest_framework.viewsets import GenericViewSet

def collect_cached_endpoints():
    cached_endpoints = []
    resolver = get_resolver()

    # 递归遍历所有路由规则
    def traverse_patterns(patterns, parent_path=""):
        for pattern in patterns:
            current_path = parent_path + pattern.pattern.regex.pattern.strip('^$')
            # 处理包含子路由的情况(如Router注册的ViewSet)
            if hasattr(pattern, 'url_patterns'):
                traverse_patterns(pattern.url_patterns, current_path + "/")
            else:
                callback = pattern.callback
                # 判断是否为ViewSet的视图类
                if hasattr(callback, 'view_class') and issubclass(callback.view_class, GenericViewSet):
                    view_class = callback.view_class
                    # 遍历ViewSet中所有@action装饰的方法
                    for name, method in inspect.getmembers(view_class, predicate=inspect.isfunction):
                        # @action装饰的方法会带有mapping属性(记录请求方法映射)
                        if hasattr(method, 'mapping'):
                            if uses_caching_func(method):
                                # 获取action的自定义路径,默认使用方法名
                                action_url = getattr(method, 'url_path', name)
                                full_path = f"/{current_path}/{action_url}".replace("//", "/")
                                # 去除末尾可能的斜杠(根据需求调整)
                                cached_endpoints.append(full_path.rstrip('/'))

    traverse_patterns(resolver.url_patterns)
    return cached_endpoints

3. 在应用启动时执行收集逻辑

在应用的apps.py中重写ready方法,确保Django启动时自动执行端点收集:

from django.apps import AppConfig

class YourAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'your_app'  # 替换为你的应用名称

    def ready(self):
        # 导入收集函数(避免循环导入)
        from .utils import collect_cached_endpoints
        cached_endpoints = collect_cached_endpoints()
        # 输出结果或存入全局变量供后续使用
        print("调用caching_func的端点列表:", cached_endpoints)

注意事项

  • 静态AST检测仅覆盖直接调用的场景,如果caching_func是通过多层函数间接调用的,需要调整检测逻辑(或改用动态检测,但动态检测可能触发业务逻辑,存在副作用)
  • 若@action装饰器指定了自定义url_path,代码已通过getattr(method, 'url_path', name)兼容该场景
  • 确保在ready方法中导入模块时避免循环导入问题,可将工具函数放在单独的utils.py文件中

内容的提问来源于stack exchange,提问作者Uche Ozoemena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:27:09