使用 post_save 信号处理程序访问新创建的模型实例的相关数据

发布于 2024-11-01 19:43:12 字数 908 浏览 1 评论 0原文

当通过管理面板创建 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 模型的管理面板更改视图?

I need to send an e-mail when new instance of Entry model is created via admin panel. So in models.py I have:

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

Then I'm registring post_save handler function:

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)  

It works, but as I mentioned before, I also need to access related attachments to include their details in the message. Unfortunatelly instance.attachments.all() returns empty list inside send_message function even if attachments were actually added.

As I figured out, when the post_save signal is sent, related data of saved model isn't saved yet, so I can't get related attachments from that place.
Question is: am I able to accomplish this using signals, or in any other way, or do I have to put this email sending code outside, for example overriding admin panel change view for Entry model?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

久随 2024-11-08 19:43:12

Maybe you could use the M2M Changed Signal instead? This signal is sent when the M2M field is changed.

泅渡 2024-11-08 19:43:12

您应该能够通过覆盖

如果您有内联,我相信您需要使用 save_formset() 相反。

You should be able to do this by overriding the save_model() method on the ModelAdmin. You could either send your email in there or fire a custom signal which triggers your handler to send the email.

If you have inlines, I believe you need to use save_formset() instead.

她如夕阳 2024-11-08 19:43:12

我尝试使用 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']} )

I tried to use ModelAdmin save_model() method, as shadfc proposed.
Anyway newly changed related objects aren't accessible from there either. But save_model takes filled form as a parameter, so I used that. My send_message isn't used as a signal handler anymore and I added related_data parameter.

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

in admin.py I have:

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']} )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文