如何在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
相关产品推荐
相关产品推荐

