Django 4 笔记 - 6.信号

使用内建信号

Django 提供了一系列内建信号,比如 pre_savepost_saverequest_startedsetting_changed 等等。

例如:想在车辆(Car)保存之后打印一条信息。

  1. 创建 cars/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Car


@receiver(post_save, sender=Car)
def onCarPostSave(sender, **kwargs):
    car = kwargs['instance']
    print(car.__str__)
  1. 修改 cars/apps.py
from django.apps import AppConfig


class CarsConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'cars'

    def ready(self):
        # Implicitly connect a signal handlers decorated with @receiver.
        from . import signals

自定义信号

举例:在添加车辆失败时,将请求参数打印出来。

  1. 修改 cars/signals.py
...
from django.dispatch import Signal

...

def onSaveCarError(sender, **kwargs):
    request = kwargs['request']
    print(request.body)

create_car_failed = Signal()    # 定义信号
create_car_failed.connect(onSaveCarError)       # 连接 Callback 函数
  1. 修改 cars/views.py
...
from .signals import create_car_failed

...
class MyCars(View):
    ...

    def post(self, request):
        '''
        添加车辆
        '''
        ...
        if form.is_valid():
            ...
            
        else:
            create_car_failed.send(sender=self.__class__, request=request)  # 发送信号
            return JsonResponse({'error': form.errors})

...

防止重复信号

在某些情况下,连接接收器到信号的代码可能被执行多次。这可能会导致接收器函数被注册多次,因此对于一个信号事件调用同样多次。例如,ready() 方法在测试期间可能被多次执行。更普遍的是,在项目的任何地方导入定义信号的模块都会发生这种情况,因为信号注册的运行次数与导入的次数相同。

如果此行为会产生问题(例如在保存模型时使用信号发送电子邮件),则传递一个唯一标识符作为 dispatch_uid 参数来标识接收方函数。这个标识符通常是一个字符串,尽管任何可散列对象都可以。最终的结果是,对于每个唯一的 dispatch_uid 值,接收器函数只与信号绑定一次:

from django.core.signals import request_finished

request_finished.connect(my_callback, dispatch_uid="my_unique_identifier")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值