天天看点

Django信号量及自定义信号量Django信号量及自定义信号量

Django信号量及自定义信号量

Django 提供一个了“信号分发器”机制,允许解耦的应用在框架的其它地方发生操作时会被通知到。 通俗而讲Django信号的工作原理就是当某个事件发生的时候会发出一个信号(signals), 而监听这个信号的函数(receivers)就会立即执行
  1. Django常用的内置信号
  • django.db.models.signals.pre_save & post_save在模型调用 save()方法之前或之后发送。
  • django.db.models.signals.pre_init& post_init在模型调用_init_方法之前或之后发送。
  • django.db.models.signals.pre_delete & post_delete在模型调用delete()方法或查询集调用delete() 方法之前或之后发送。
  • django.db.models.signals.m2m_changed在模型多对多关系改变后发送。
  • django.core.signals.request_started & request_finished Django建立或关闭HTTP 请求时发送。

2. 如何正确放置Django信号的监听函数代码

把所以自定义的信号监听函数集中放在app对应文件夹下的signals.py文件里,便于后期集中维护。

# account/models.py

from django.db import models


class User(models.Model):
    name = models.CharField(max_length=16)
    gender = models.CharField(max_length=32, blank=True)


class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    birth_date = models.DateField(null=True, blank=True)
           

# account/signals.py

from django import dispatch
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import User, Profile


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
           

# account/apps.py

from django.apps import AppConfig


class AccountConfig(AppConfig):
    name = 'account'

    def ready(self):
        import account.signals
           

3. 自定义信号量

  • a.定义信号  # account/signals.py
# 自定义信号量
custom_signal = dispatch.Signal(providing_args=["new_obj"])
           

    b.将监听函数与信号相关联  # account/signals.py

@dispatch.receiver(custom_signal)
def custom_signal_func(sender, **kwargs):
    print('自定义信号量回调函数')
    print(sender)
    new_obj = kwargs.get("new_obj", None)
    print(new_obj)
           
  • c.触发信号  # account/views.py

视图中进行某个操作时可以使用send方法触发自定义的信号,并设定providing_args列表中的值

from django.http import JsonResponse
from account.signals import custom_signal


def test(requset):
    custom_signal.send(sender='seven', new_obj='test_new_obj')
    return JsonResponse({"code": "200"})