天天看點

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"})