django - Django 两种相同的信号类型
问题描述
我不明白一起执行的 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 实例并保存它。
发件人:是实际发出信号的模型。所以在我们的例子中,如果我们希望在用户模型上执行保存方法时发出信号,那么发送者就是用户。
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 函数(例如 create_profile 或 save_profile 主体)。
我假设当保存用户实例时执行 create_profile 函数,它会生成一个配置文件对象,然后执行 save_profile 函数,并且对于相同的用户实例,保存配置文件对象,但我仍然不明白它是如何知道我指的是同一个该实例制作的配置文件。
解决方案
为什么你不说它是 Corey 教程的例子?
Corey 教程,第 8 部分,如果我没记错的话,他不必创建两个单独的信号,因为一个就足够了..
对于您的问题:功能是:
@receiver(post_save, sender=User)
def create_profile_handler(sender, instance, created, **kwargs):
#Run each time a new user is created, and attach to the user a profile !
# sender - The model class (User)
# instance - The actual instance being saved. (User)
# created - A boolean. 'True' if a new record was created.
if created:
Profile.objects.create(user=instance)
#'create' - initialize and save a profile and attach it to the User
# Now, lets save the profile each time the user object is been saved.
@receiver(post_save, sender=User)
def save_profile_handler(sender, instance, **kwargs):
instance.profile.save() # User.profile.save() - saves the profile
我们从 Django Docs中知道,create() 方法中包含 save() 操作。
因此,不仅第二个信号是多余的(因为我们可以在第一个信号中执行它的操作),而且 - save 本身有点多余(因为 create 调用 save)。
推荐阅读
- python - 接受连接的时间
- progressive-web-apps - 此浏览器不支持 ServiceWorkers 消息
- javascript - 更改 @Input 组件对象不会反映在父组件中
- python - Python 多处理队列管理器地址已在使用中
- katalon-studio - Katalon - 在隐身模式下录制
- android - Android:相同的型号,其中一部手机正在从 Play 商店获取更新的应用程序,但另一部手机没有获取更新的应用程序
- swift - 使用 Cocoapods 安装 swift 库
- mysql - Docker Compose Sql DB 镜像连接错误
- javascript - 如何以编程方式取消 AlertIOS
- firebase - 如何限制用户根据 Firebase 规则中的电话号码读取/写入数据