Доступ к связанным данным вновь созданного экземпляра модели с помощью обработчика сигнала post_save - PullRequest
5 голосов
/ 15 апреля 2011

Мне нужно отправить электронное письмо при создании нового экземпляра модели Entry через панель администратора.Так что в models.py у меня есть:

class Entry(models.Model):   
    attachments = models.ManyToManyField(to=Attachment, blank=True)
    #some other fields
    #...
    sent = models.BooleanField(editable=False, default=False)

Затем я регистрирую функцию обработчика post_save:

def send_message(sender, instance, **kwargs):
    if not instance.sent:
        #sending an e-mail message containing details about related attachments
        #...
        instance.sent = True
        instance.save()

post_save.connect(send_message, sender=Entry)  

Это работает, но, как я упоминал ранее, мне также нужно получить доступ к связаннымвложения, чтобы включить их детали в сообщение.К сожалению, instance.attachments.all() возвращает пустой список внутри функции send_message, даже если вложения действительно были добавлены.

Как я выяснил, при отправке сигнала post_save соответствующие данные сохраненной модели еще не сохраняются, поэтому яне могу получить связанные вложения из этого места.Вопрос в том, могу ли я выполнить это с помощью сигналов или любым другим способом, или я должен поместить этот код отправки электронной почты снаружи, например, переопределив представление изменения панели администратора для Entry модель?

Ответы [ 3 ]

2 голосов
/ 15 апреля 2011

Может быть, вы могли бы вместо этого использовать M2M Changed Signal ?Этот сигнал отправляется при изменении поля M2M.

1 голос
/ 16 апреля 2011

Я пытался использовать метод ModelAdmin save_model(), как предложил shadfc.В любом случае, недавно измененные связанные объекты также не доступны оттуда.Но save_model принимает заполненный form в качестве параметра, поэтому я использовал это.Мой send_message больше не используется в качестве обработчика сигнала, и я добавил параметр related_data.

def send_message(sender, instance, related_data={}):
    #sending e-mail using related_data parameter to access additional related objects
    #...

в admin.py У меня есть:

class EntryAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.save()
        send_message(sender=Entry, instance=obj,
                     related_data={'attachments': form.cleaned_data['attachments']} )
1 голос
/ 16 апреля 2011

Вы можете сделать это, переопределив метод save_model () в ModelAdmin. Вы можете отправить туда свою электронную почту или создать собственный сигнал, который заставляет ваш обработчик отправлять электронную почту.

Если у вас есть встроенные строки, я считаю, что вам нужно использовать save_formset () вместо.

...