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 be 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With