python - 对于从父类继承的模型,Django 不发送 save() 信号?

标签 python django model signals

我刚刚在我的模型上设置了继承,这对我的项目来说更有意义——一切都继承自 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")

模型.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 信号而不是一揽子规则。

最佳答案

当我想为所有子模型类添加一个 pre_save 信号但我只想在一个地方实现时,我认为遇到了类似的问题。使用 python 3.6+ 可以解决这个问题,因为它需要 __init_subclass__ 魔法方法。

子模型子类没有自动注册信号的问题。因此,您可以在 init_subclass 函数中为子模型注册信号,而不是手动注册信号

下面的代码示例显示了实现的要点:

Class BaseModel:
      common_field = models.CharField(...)
      
     @classmethod
        def __init_subclass__(cls, **kwargs):
            super().__init_subclass__(**kwargs)
            # automatically bind the pre_save for the sub model
            pre_save.connect(generate_common_field, cls)
    
    
   def generate_common_field:
     pass

Class SubModel(BaseModel):
    pass

关于python - 对于从父类继承的模型,Django 不发送 save() 信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56147522/

相关文章:

python - 用 Python ping 一个站点?

python - ViewSets 是否在 Django Rest Framework 中生成 view_names?

node.js - Sequelize include 不适用于关联表

entity-framework - Entity Framework 查询到带有列表的自定义对象类

python - 更新字典中的嵌套计数器

jquery.ajax 发布请求以从应用引擎服务器获取数据

python - Django 覆盖单元测试中的 settings.py OBJECT 不起作用

python - 如何确保调试配置中没有 pdb 调用?

django - 按 Django 中的总和排序查询,但未按预期获得结果

ruby-on-rails - 从符号中获取模型类