开发者

django post_save signal sends outdated inline formsets

开发者 https://www.devze.com 2023-01-23 14:02 出处:网络
Consider the following: class OrderForm(models.Model): title = models.CharField(max_length=100) desc= models.TextField()

Consider the following:

class OrderForm(models.Model):
    title = models.CharField(max_length=100)
    desc  = models.TextField()


class OrderFormLine(models.Model):
    order = models.ForeignKey(OrderForm)
    lagel = models.CharField(max_length=100)
    qty   = models.IntegerField(...)
    price = models.FloatField(...)

Now I want to send an email with the orderform details whenever someone creates one or modify one.

No rocket science so far .. let's just use a post_save signal;

post_save.connect(email_notify, sender=OrderForm)

But there's one tiny problem, the OrderForm object passed to email_notify is updated with the new data as expected, but not the related OrderFormLine items.

I've tried to override the save methods in the admin AND in the model, I've tried to save the object, the form and its relation before passing it to my notification handler, nothing works.

I'm aware that I could attach the post_save signal to the OrderItem model, but then the email would b开发者_如何学运维e sent for each items.

Help I'm on the brink of madness.

UPDATE:

Found a simple and reliable solution

Short story:

def email_notify_orderform(sender, **kwargs):
    instance = kwargs['instance']
    ct = ContentType.objects.get_for_model(OrderForm)
    if ct.id == instance.content_type.id:
        print instance.is_addition()
        print instance.is_change()
        print instance.is_deletion()
        print instance.change_message
        print instance.action_time
        print instance.get_edited_object().total() # BINGO !
post_save.connect(email_notify_orderform, sender=LogEntry)


The basic problem is that when the main objects post_save signal is sent, the inlines have not been saved yet: the parent model always gets saved first. So, it's not that it's sending old data; in fact it's the current state of the data.

The simplest solution is to create a custom signal and have that signal sent at a place where the inlines have been saved. The save_formset method on ModelAdmin is your hook.

0

精彩评论

暂无评论...
验证码 换一张
取 消