【发布时间】:2019-10-02 11:46:10
【问题描述】:
我刚刚在我的模型上设置了继承,这对我的项目更有意义 - 一切都继承自 Item 类,具有公共元素。然后将其他字段添加到子类 - 视频、播客、文章等...
以前,在 Item.save() 上,我设置了一些 pre_save 和 post_save 信号,它们在我的 Item 模型对象上解析/执行各种任务。
@receiver(pre_save, sender=Item)
def some_function(sender, instance, *args, **kwargs):
print("I am working")
但是,现在我的对象都是 Item 的子类,这些信号似乎没有被触发。
>Article.objects.get_or_create(title='some title')
@receiver(pre_save, sender=Article)
def some_function(sender, instance, *args, **kwargs):
print("I am not doing anything")
models.py
class Item(models.Model, AdminVideoMixin):
title = models.TextField(max_length=2000)
slug = models.SlugField(max_length=500, default='')
link = models.URLField(max_length=200)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(get_random_string(length=5,allowed_chars='1234567890') + '-' + self.title)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('curate:item_detail',args=[self.slug])
def __str__(self):
return self.title
class Video(Item):
video_embed = EmbedVideoField(max_length=300)
channel = models.TextField(max_length=500, blank=True
def __str__(self):
return self.title.upper()
class Article(Item):
authors = models.CharField(max_length=10000)
movies = models.TextField(max_length=10000)
def __str__(self):
return self.title.upper()
class Podcast(Item):
authors = models.CharField(max_length=10000)
itune_image = models.CharField(max_length=10000)
owner_name = models.CharField(max_length=10000)
def __str__(self):
return self.title.upper()
class Episode(Item):
authors = models.CharField(max_length=10000)
itune_image = models.CharField(max_length=10000)
owner_name = models.CharField(max_length=10000)
enclosure_url = models.URLField(max_length=2000)
owner = models.ForeignKey(Podcast, on_delete=models.CASCADE,max_length=2000)
class Meta:
pass
def __str__(self):
return self.title.upper()
我什至按照this thread 将接收器堆叠起来,以防它应该由父类和子类触发,但它仍然没有保存。
@receiver(post_save, sender=Video)
@receiver(post_save, sender=Item)
@receiver(post_save, sender=Article)
def some_function(sender, instance, *args, **kwargs):
print('This still didn't fire')
还尝试使用 post_save.connect(some_function, sender=Article),但无法触发信号。我正在使用 get_or_create(attributes) 创建对象
我是否必须手动编写一些东西才能进入并执行预发布/保存,还是我做错了什么?我看到了a solution,但这建议将信号发送给所有子类——不管是哪个——但这不是我想要的。我想设置模型特定的 post_save / pre_save 信号而不是一揽子规则。
【问题讨论】:
-
save()不会将保存前/保存后信号发送到父类(因为不能保证父表会实际保存,因为这只需要在字段打开时发生父模型受到影响)。delete()确实传播到父类 btw,因此信号处理程序适用于例如post_delete。但是,将所有类堆叠为接收器应该可以工作,所以不起作用的原因在于其他地方。您确定您的信号处理程序已处理(在启动时读取的文件中)吗?更改后您是否重新启动了服务器? -
您提到的解决方案也不是“向所有子类发送信号”,它将接收器连接到所有子类,正是您想要的(基本上与堆叠接收器相同,但没有以后创建新子类时要记住添加一个的麻烦)。
-
我使用与以前完全相同的 signals.py 脚本(在应用程序文件夹内) - 我在脚本顶部导入了我可能需要的所有信号。 from django.contrib.auth.models import User from django.db.models.signals import post_save, pre_save
-
我可以确认对象正在保存 - 它们在我的管理页面中,我可以在 shell 中与它们互动。
-
感谢您的帮助 - 您是对的,问题来自其他地方。我正在使用一个名为报纸的包 - 但它实际上是作为文章导入的。所以我的signals.py 中有两个“Article”对象,Python/Django 没有抛出错误。我以不同的名称重新导入报纸 ArticleNewspaper
标签: python django model signals