【发布时间】:2021-04-01 07:42:26
【问题描述】:
我不明白一起执行的 2 个信号如何相互关联。例如考虑以下内容:
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
from django.db.models.signals import post_save
from django.dispatch import receiver
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
# Overriding save method-image resizing
def save(self, **kwargs):
super().save(kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path) # save() of parent class
#Signals when a user is registered his profile is automatically updated
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile(user=instance) #could do Profile.objects.create(user=instance) instead to replace the 2 lines
instance.profile.save() #reverse query
我了解以下内容:
create_profile: 是我的接收函数。当 .save() 方法发生时它会做一些事情,在我们的例子中会创建一个 Profile 实例并保存它。
sender:是实际发出信号的模型。所以在我们的例子中,如果我们希望在用户模型上执行保存方法时发出信号,那么发送者就是用户。
post_save 是信号
关于我现在的问题。我已经看到上面的函数分解成以下两个函数。
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile(user=instance)
@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save() #reverse query
我知道这是没有意义的,因为我可以做我所做的,但我不明白我的 save_profile 函数如何“记住”在 create_profile 上创建的 Profile 实例?
据我所知,save_profile 是一个单独的函数,它没有引用 create_profile 函数(例如 save_profile 主体中的 create_profile 等)。
我假设当一个用户实例被保存时 create_profile 函数被执行它会创建一个配置文件对象然后 save_profile 函数被执行并且对于相同的用户实例配置文件对象被保存, 但我仍然不明白它是如何知道我引用了该实例创建的相同配置文件。
【问题讨论】:
-
其实信号不是同时执行,而是顺序执行
标签: django