Django: обработчик сигнала базовой модели не срабатывает - PullRequest
6 голосов
/ 04 октября 2011

В следующем примере кода:

from django.db import models
from django.db.models.signals import pre_save

# Create your models here.
class Parent(models.Model):
    name = models.CharField(max_length=64)

    def save(self, **kwargs):
        print "Parent save..."
        super(Parent, self).save(**kwargs)

def pre_save_parent(**kwargs):
    print "pre_save_parent"
pre_save.connect(pre_save_parent, Parent)

class Child(Parent):
    color = models.CharField(max_length=64)

    def save(self, **kwargs):
        print "Child save..."
        super(Child, self).save(**kwargs)

def pre_save_child(**kwargs):
    print "pre_save_child"
pre_save.connect(pre_save_child, Child)

pre_save_parent не срабатывает, когда я создаю ребенка:

child = models.Child.objects.create(color="red")

Это ожидаемое поведение?

Ответы [ 2 ]

6 голосов
/ 04 октября 2011

Об этом есть открытый билет, # 9318 .

Ваш обходной путь выглядит хорошо.Вот еще два предложения, предложенные в заявке: benbest86 и alexr соответственно.

  1. Прослушивание сигнала дочернего класса и отправка сигнала Parentтам.

    def call_parent_pre_save(sender, instance, created, **kwargs):
        pre_save.send(sender=Parent, instance=Parent.objects.get(id=instance.id), created=created, **kwargs)
    pre_save.connect(call_parent_pre_save, sender=Child)
    
  2. Не указывайте отправителя при подключении сигнала, затем проверьте подклассы родителя.

    def pre_save_parent(sender, **kwargs):
        if not isinstance(instance, Parent):
            return
        #do normal signal stuff here
        print "pre_save_parent"
    
    pre_save.connect(pre_save_parent)
    
2 голосов
/ 04 октября 2011

Я не знал, что sender является необязательным параметром для connect. Я могу сделать следующее:

def pre_save_handler(**kwargs):
    instance = kwargs['instance']
    if hasattr(instance, 'pre_save'):
        instance.pre_save()
pre_save.connect(pre_save_handler)

Это позволяет мне писать для каждой модели pre_save методы, и они в свою очередь могут вызывать любые версии базового класса (если они существуют).

Есть ли лучшие решения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...