62

I need to do some background post-processing on newly created objects in Django. This post-processing should only run on new objects, not objects that are just updated.

I know that in pre_save I can check if the object has an id, if it has not then it's a new object. But the problem is that in the post-processing I need access to the id (so that I can save the results back to the database).

How can I do this in a clean way?

Artem Likhvar
  • 103
  • 2
  • 7
Jon Tirsen
  • 4,750
  • 4
  • 29
  • 27
  • 2
    Is it at all possible to do the processing after the actual save? Then use post_save, https://docs.djangoproject.com/en/dev/ref/signals/#django.db.models.signals.post_save. It has a boolean to say whether it's new or just an update. – andersem May 20 '12 at 10:31

3 Answers3

97

Have a look at docs: https://docs.djangoproject.com/en/stable/ref/signals/#post-save

There is a created named argument which will be set to True if it's a new object.

Tim Tisdall
  • 9,914
  • 3
  • 52
  • 82
seler
  • 8,803
  • 4
  • 41
  • 54
30

As Docs stated and @seler pointed out, but with an example:

def keep_track_save(sender, instance, created, **kwargs):
    action = 'save' if created else 'update'
    save_duplicate((instance.id, instance.__class__.__name__, action))

post_save.connect(keep_track_save, sender=Group)
elad silver
  • 9,222
  • 4
  • 43
  • 67
11

I just leave it here, maybe it'll be helpful for someone.

from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver


class Deal(models.Model):
    name = models.CharField(max_length=255)


@receiver(post_save, sender=Deal)
def print_only_after_deal_created(sender, instance, created, **kwargs):
    if created:
        print(f'New deal with pk: {instance.pk} was created.')
Alexandr S.
  • 1,607
  • 1
  • 14
  • 16