2009-08-03 3 views
9

Im пытается подключить объект «Информация» ко многим «Заказчикам» (см. Код ниже)Почему сигнал Django post_save дает мне данные pre_save?

Когда один объект информации обновлен, я хочу отправить электронное письмо каждому клиенту, который подключен к Информации.

Однако, когда я регистрирую поле sold_to, которое получает сигнал, я всегда получаю данные, подобные ПЕРЕД сохранением.

Я предполагаю, что это связано с тем, что его ManyToManyField и данные хранятся в отдельной таблице, но не следует ли вызывать сигнал post_save после того, как все отношения были обновлены?

У кого-нибудь есть предложение для решения?

class Customer 
    name = models.CharField(max_length=200) 
    category = models.ManyToManyField('Category',symmetrical=False) 
    contact = models.EmailField() 

class Information 
    name = models.CharField(max_length=200) 
    email = models.EmailField(max_length=200) 
    mod_date = models.DateTimeField(auto_now=True) 
    sold_to = models.ManyToManyField(Customer, null=True, blank=True) 


def send_admin_email(sender, instance, signal, *args, **kwargs): 
    from myapp import settings 
    for cust in instance.sold_to.all(): 
     settings.debug(cust.name) 

post_save.connect(send_admin_email, sender=Information) 

Edit: Apollo13 в #django предупредил меня к этому: «Посторонние предметы (вещи, которые сохраняются в многие-ко-многим) не сохраняются как часть модели Сохраним метод, как вы обнаружили ». - http://groups.google.com/group/django-users/msg/2b734c153537f970

Но с момента его получения с 9 июля 2006 года я действительно очень надеюсь, что для этого есть решение.

ответ

5

Существует открытый билет на выпуск, с которым вы сталкиваетесь here. Вы можете либо следить за этим, когда это делает его выпуском, либо вы можете попробовать применить исправление, которое оно предоставляет, и посмотреть, помогает ли это.

+0

Благодарим за быстрый ответ. Я попробовал патч, и после небольшого взлома я получил его на работу. Выведет решение ниже. – schmilblick

1

Это мое решение после применения исправления от code.djangoproject.com, упомянутого выше.

Добавлено это в models.py:

from django.db.models.signals import m2m_changed 
m2m_changed.connect(send_admin_email, sender=Information) 

И send_admin_email функция:

def send_customer_email(sender, instance, action, model, field_name, reverse, objects, **kwargs): 
    if ("add" == action): 
     # do stuff 
1

Я бегу по тому же вопросу, так как я M2M поля в моей модели я также получили pre_save как данные.

В этой ситуации проблема заключается в том, что в полях M2M обе связанные модели должны быть сохранены для получения автоматически сгенерированных идентификаторов.

В моем решении ни я не использовал сигнал post_save, ни сигнал m2m_changed, вместо этих сигналов я использовал методы log_addition и log_change в определении класса ModelAdmin.

В пользовательском классе ModelAdmin:

class CustomModelAdmin(admin.ModelAdmin): 
     def log_addition(self, request, object): 
     """ 
     Log that an object has been successfully added. 
     """ 
      super(CustomModelAdmin, self).log_addition(request, object) 
      #call post_save callback here object created 

     def log_change(self, request, object): 
     """ 
     Log that an object has been successfully changed. 
     """ 
      super(CustomModelAdmin, self).log_change(request, object) 
      #call post_save callback here object changed 

Если вы хотите, вы можете также переопределить метод log_deletion().

Happy overriding ...

Смежные вопросы