马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
Django信号(Signals)是一种答应应用组件在特定事件发生时举行通讯的机制,而不必直接引用相互。它遵循观察者模式,答应发送者(如模型实例的保存或删除)发送信号,而吸收者(信号处理器)可以监听这些信号并作出响应,从而实现松耦合的组件间通讯。
Django内置信号
模型(Model)相干的信号
- pre_init:在Django模型实例化其构造方法之前触发。
- post_init:在Django模型实例化其构造方法之后触发。
- pre_save:在Django模型对象保存到数据库之前触发。
- post_save:在Django模型对象保存到数据库之后触发,无论对象是新建还是更新。
- pre_delete:在Django模型对象从数据库中删除之前触发。
- post_delete:在Django模型对象从数据库中删除之后触发。
- m2m_changed:在利用Many-to-Many字段举行添加、移除或清空操作前后触发。
- class_prepared:当Django发现并准备利用已注册应用中的模型类时触发。
数据库迁移相干的信号
- pre_migrate:执行migrate下令前触发。
- post_migrate:执行migrate下令后触发。
请求和响应相干的信号
- request_started 和 request_finished:分别在Django开始处理HTTP请求和完成请求处理后触发。
- got_request_exception:当视图函数中抛出异常时触发。
测试相干的信号
- Test signals:在测试运行的不同阶段触发,用于测试情况的设置或清理等。
其他信号
- setting_changed:当Django设置在运行时被更改时触发。
- template_rendered:模板渲染完成后触发,可用于模板调试。
利用场景
- 日志记录:在模型保存或删除时自动记录日志。
- 关照系统:用户操作后发送邮件或短信关照。
- 权限查抄:在模型保存前查抄用户是否有相应权限。
- 数据同步:数据库更改后同步到搜刮引擎或缓存系统。
- 清理使命:删除模型实例时,同步清理关联的文件或资源。
- 异步处理:在视图操作后触发异步使命,如发送邮件、处理图像等。
利用示例
假设我们有一个如下User模型,我们盼望每次有User对象新创建时都打印出有新用户注册的提示信息,我们可以利用Django信号(signals)轻松实现。我们的信号发送者sender是User模型,每当User模型执行post_save动作时就会发出信号。此时我们自定义的create_user函数一旦监听到User发出的post_save信号就会执行,先通过if created判断对象是新创建的还是被更新的;假如对象是新创建的,就会打印出提示信息。
- from django.db import models
- from django.db.models.signals import post_save
- from django.dispatch import receiver
- class User(models.Model):
- name = models.CharField(max_length=16)
- gender = models.CharField(max_length=32, blank=True)
- def create_user(sender, instance, created, **kwargs):
- if created:
- print("New user created!")
- post_save.connect(create_user, sender=User)
复制代码 在上例中我们利用了信号(post_save)自带的connect的方法将自定义的函数与信号发出者(sender)User模型举行了连接。在现实应用中一个更常用的方式是利用@receiver装饰器实现发送者与监听函数的连接,如下所示。@receiver(post_save, sender=User)读起来的意思就是监听User模型发出的post_save信号。
- from django.db import models
- from django.db.models.signals import post_save
- from django.dispatch import receiver
- class User(models.Model):
- name = models.CharField(max_length=16)
- gender = models.CharField(max_length=32, blank=True)
- @receiver(post_save, sender=User)
- def create_user(sender, instance, created, **kwargs):
- if created:
- print("New user created!")
复制代码
在Django中,request_started, request_finished, 和 got_request_exception 这三个信号可以用于在请求处理的不同阶段执行特定的代码逻辑,例如日志记录、性能监控、资源管理等。以下是利用这些信号的根本步调:
- #your_app/single.py
- from django.core.signals import request_started, request_finished, got_request_exception
- from django.dispatch import receiver
- @receiver(request_started)
- def on_request_started(sender, environ, **kwargs):
- # 在这里添加处理逻辑,比如开始记录请求时间、初始化日志上下文等
- print("Request started.")
- @receiver(request_finished)
- def on_request_finished(sender, **kwargs):
- # 在这里添加处理逻辑,比如记录请求结束时间、计算请求耗时、清理资源等
- print("Request finished.")
- @receiver(got_request_exception)
- def on_request_exception(sender, request, **kwargs):
- # 在这里添加处理逻辑,比如记录异常信息、发送报警等
- print("Exception occurred during request processing:", request)
复制代码 注册信号处理器:
- # your_app/apps.py
- from django.apps import AppConfig
- from django.core.signals import request_started, request_finished, got_request_exception
- from .signals import on_request_started, on_request_finished, on_request_exception
- class YourAppConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'your_app'
- def ready(self):
- # 注册信号处理器
- request_started.connect(on_request_started)
- request_finished.connect(on_request_finished)
- got_request_exception.connect(on_request_exception)
复制代码 自定义信号
首先,你必要定义一个新的信号。这通常在应用的一个单独的signals.py文件中完成。信号通过django.dispatch.Signal类来定义,并可以指定信号发送时必要携带的参数。
- #创建一个名为APP01的应用
- # APP01/signals.py
- from django.dispatch import Signal
- from django.dispatch import receiver
- # 定义一个自定义信号,提供额外的参数example_arg
- my_custom_signal = Signal(providing_args=['example_arg'])
- #注册信号回调函数
- @receiver(my_custom_signal)
- def my_signal_handler(sender, **kwargs):
- example_arg = kwargs.get('example_arg', "No argument provided.")
- print(f"Custom signal received with argument: {example_arg}")
- # 在这里执行你的逻辑,比如记录日志、更新数据库、发送邮件等
复制代码 然后注册信号处理器,你可以在应用的apps.py文件的ready()方法中注册这些信号处理器,确保它们在Django启动时被正确注册。
- # APP01/apps.py
- from django.apps import AppConfig
- from .signals import my_signal_handler
- class YourAppConfig(AppConfig):
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'your_app'
- def ready(self):
- # 连接信号处理器
- my_custom_signal.connect(my_signal_handler)
复制代码 发送信号
- # 例如,在某个视图中发送信号
- from django.http import HttpResponse
- from .signals import my_custom_signal
- def some_view(request):
- # 执行某些操作...
- # 例如当用户成功登录的时候....
- my_custom_signal.send(sender=None, example_arg="This is an example argument.")
- return HttpResponse("Signal sent.")
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |