Django中的Signals
Signals 官方文档https://docs.djangoproject.com/en/3.0/topics/signals/
基本上是由发送一些信息的发送者和接收者组成, 给接收者或发生任何事
说人话是一些操作发生的时候,系统会根据信号的定义的函数执行相应的操作
Django提供了一组内置的信号,这些信号使得Djano自身可以将某些操作通知给用户
在save()
调用models 之前或之后发送。
-
django.db.models.signals.pre_save
和django.db.models.signals.post_save
- 在调用models 的
delete()
方法或查询集的delete()
方法之前或之后发送。 -
django.db.models.signals.pre_delete
和django.db.models.signals.post_delete
ManyToManyField
更改模型上的a 时发送。-
django.db.models.signals.m2m_changed
- 在Django 开始 或结束 HTTP请求时发送
-
django.core.signals.request_started
和django.core.signals.request_finished
用post_save做例子
A方法一 .connect
-建立models.py用来创建模型 Profile
继承user模型
from django.db import models from django.contrib.auth.models import User # Create your models here. class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True) first_name = models.CharField(max_length=200, null=True, blank=True) last_name = models.CharField(max_length=200, null=True, blank=True) phone = models.CharField(max_length=200, null=True, blank=True) def __str__(self): return str(self.user)
-建立signals.py用来 注册信号‘
参数 sender(发送方) 是发送信号的模型
instance (模型的实例) 以便发送它的实际对象或是项目
created(创造) 如果这是该商品的首次创建或者是更新
from django.db.models.signals import post_save def create_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) print('Profile created!') post_save.connect(create_profile, sender = User) def update_profile(sender, instance, created, **kwargs): if created == False: instance.profile.save() print('Profile updated!') post_save.connect(update_profile, sender =User)
这个两个函数都将被触发 但是他们的响应Respon会有所不同 当我们创建一个用户时 会自动调用create_profile
更新一个用户时,会自动调用update_profile
-引用配置文件
在apps.py 中配置
from django.apps import AppConfig class BaseConfig(AppConfig): name = 'base' def ready(self): import base.signals
在settings.py中配置
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'base.apps.BaseConfig' ]
B方法二 使用装饰器
-在signals.py里面创建装饰器
引入djanog.dispath receiver
from django.db.models.signals import post_save from django.dispatch import receiver from django.contrib.auth.models import User from .models import Profile @receiver(post_save, sender=User) def create_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) print('Profile created!') #post_save.connect(create_profile, sender=User) @receiver(post_save, sender=User) def update_profile(sender, instance, created, **kwargs): if created == False: instance.profile.save() print('Profile updated!') #post_save.connect(update_profile, sender=User)
-最后一步配置文件也可以改成在__init__.py中配置
default_app_config = 'base.apps.BaseConfig'
利用Signals改善之前的crm代码
-创建signals.py
创建用户成功后后台发送 Customer was created
from django.db.models.signals import post_save from .models import * from django.contrib.auth.models import User,Group def customer_profile(sender , instance , create ,**kwargs): if create: group = Group.objects.get(name='customer') instance.groups.add(group) Customer.objects.create( user=instance, name=instance.username, )
print('Customers was created') post_save.connect(customer_profile, sender=User)
-配置文件
在apps.py中
from django.apps import AppConfig class AccountsConfig(AppConfig): name = 'accounts' def ready(self): import accounts.signals
在settings.py中
记得加逗号!
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_filters', 'accounts.apps.AccountsConfig', ]