You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DjangoBlog-Maintenance-Anal.../src/hooks.py

92 lines
4.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 导入logging模块用于记录钩子系统运行过程中的日志如注册信息、错误信息等
import logging
# 创建当前模块的日志记录器,日志名称与模块绑定,便于区分不同组件的日志输出
logger = logging.getLogger(__name__)
# 全局钩子存储字典,用于保存所有注册的钩子及其对应的回调函数
# 键:钩子名称(字符串,如"article_create"
# 值:回调函数列表(所有注册到该钩子的可调用对象将按注册顺序存储)
_hooks = {}
def register(hook_name: str, callback: callable):
"""
注册一个钩子回调函数,将其添加到指定钩子名称对应的回调列表中
核心作用:建立"钩子名称""处理逻辑(回调函数)"的映射关系,
使后续触发钩子时能自动执行所有注册的回调
:param hook_name: 钩子名称字符串需与触发时使用的名称一致如ARTICLE_CREATE
:param callback: 可调用对象(函数、方法等),当钩子被触发时会执行此对象
回调函数的参数需与钩子触发时传递的参数匹配
"""
# 若钩子名称尚未在全局字典中,初始化一个空列表用于存储回调
if hook_name not in _hooks:
_hooks[hook_name] = []
# 将回调函数添加到对应钩子的列表中(按注册顺序存储,触发时也按此顺序执行)
_hooks[hook_name].append(callback)
# 记录DEBUG级日志说明钩子注册成功包含钩子名称和回调函数名便于调试
logger.debug(f"Registered hook '{hook_name}' with callback '{callback.__name__}'")
def run_action(hook_name: str, *args, **kwargs):
"""
执行指定名称的"动作钩子Action Hook",按注册顺序调用所有关联的回调函数
动作钩子特性:用于触发一系列操作,不关注返回值,仅执行回调逻辑
典型场景:文章创建后发送通知、记录日志等(执行动作但无需修改数据)
:param hook_name: 要触发的钩子名称(需已被注册过)
:param *args: 传递给回调函数的位置参数(可变参数,根据钩子场景定义)
:param **kwargs: 传递给回调函数的关键字参数(可变参数,根据钩子场景定义)
"""
# 检查该钩子是否有已注册的回调函数
if hook_name in _hooks:
# 记录DEBUG级日志说明开始执行该动作钩子
logger.debug(f"Running action hook '{hook_name}'")
# 按注册顺序遍历所有回调函数并执行
for callback in _hooks[hook_name]:
try:
# 传递位置参数和关键字参数给回调函数
callback(*args, **kwargs)
except Exception as e:
# 若回调执行出错记录ERROR级日志包含详细异常信息
# exc_info=True 会在日志中附带堆栈跟踪,便于排查错误
logger.error(
f"Error running action hook '{hook_name}' callback '{callback.__name__}': {e}",
exc_info=True
)
def apply_filters(hook_name: str, value, *args, **kwargs):
"""
执行指定名称的"过滤钩子Filter Hook",通过回调函数链式处理初始值并返回最终结果
过滤钩子特性:用于对数据进行加工处理,每个回调函数接收上一个函数的输出作为输入,
最终返回经过所有回调处理后的值
典型场景:文章内容过滤敏感词、格式化文本等(修改数据并返回新值)
:param hook_name: 要触发的钩子名称(需已被注册过)
:param value: 初始值(需要被过滤/处理的数据,如文章内容字符串)
:param *args: 传递给回调函数的额外位置参数
:param **kwargs: 传递给回调函数的额外关键字参数
:return: 经过所有回调函数处理后的最终值
"""
# 检查该钩子是否有已注册的回调函数
if hook_name in _hooks:
# 记录DEBUG级日志说明开始执行该过滤钩子
logger.debug(f"Applying filter hook '{hook_name}'")
# 按注册顺序遍历所有回调函数,链式处理初始值
for callback in _hooks[hook_name]:
try:
# 调用回调函数,将当前值和额外参数传入,更新值为回调返回的结果
value = callback(value, *args, **kwargs)
except Exception as e:
# 若回调执行出错记录ERROR级日志包含详细异常信息
logger.error(
f"Error applying filter hook '{hook_name}' callback '{callback.__name__}': {e}",
exc_info=True
)
# 返回经过所有过滤处理后的最终值
return value