Accessing the new model instance with Django’s “post_save” signal

I’d been wracking my brain for a few hours before I finally went back to the Django signals documentation and looked up how to get to the newly created instance with Django’s ‘post_save’ signal. I’m not sure if johnboxall’s django-paypal signal example is out of date or simply erroneous, but it’s not the right way to do it. I’d expected the sender itself to be the new instance. Instead, this:

def notify_on_payment(sender, **kwargs):
  print "We got it"
  ipn_obj = sender
  print ipn_obj

post_save.connect(notify_on_payment, sender=PayPalIPN)

got me this:

We got it
<class 'paypal.standard.ipn.models.PayPalIPN'>

…plus a big fat error page in the browser.

Note: I couldn’t get the payment_was_successful signal to work at all, so I rolled my own.

The <class> bit is NOT the newly created instance, but the class itself. Django did not like me trying to access the ‘id’ of a Model class.

Long story short, the actual instance is passed as a keyword argument. Here’s how to get to it:

def notify_on_payment(sender, **kwargs):
  print "We got it"
  ipn_obj = kwargs['instance']
  print ipn_obj

Here’s the output:

We got it
<IPN: Recurring > #This is the get_display for this particular Model

Much better :). I can now access fields on that instance using dot notation.

I’d be interested in knowing whether the example on johnboxall’s page is outdated or wrong. It would seem reasonable to me for the sender to be the newly created instance to send the signal. I am, however, usually wrong about these things. Any ideas?

Leave a Reply

Your email address will not be published.

= 4 + 4