Django pre_save signal: check if instance is created not updated, does kwargs['created'] (still) exist?

Question:

I am using Django’s pre_save signal to implement auto_now_add. There is a lot of discussion on the internet on why you should or shouldn’t implement it yourself. I do not appreciate comments on this. Neither on whether I should be rewriting the save function (I have a lot of models that use auto_now_add so using signals makes sense).

My question is:
I would like to check if the instance is created or updated. According to some sources on the internet this can be done by testing if kwargs['created'] is True. However 'created' does not appear in my kwargs even though the instance is newly created.
I was just wondering if it has ever existed or that it has disappeared magically.
I know I could also test if kwargs['instance'].id is set (this in fact works for me), but I’d like to know if kwargs[‘created’] still exists.

Asked By: Heyl1

||

Answers:

According to the latest Django documentation, pre_save does NOT send a created argument. Post_save however does. I could not find any reference of the signal sending created since version 1.0.

Answered By: Manoj Govindan

Primary key attribute usually assigned by the database when the instance saved first time. So you can use something like if instance.pk is None

Answered By: Radagast

I am not sure if this is the recommended way but @Radagast’s method didnt work for me(not sure if its because I use custom Pk’s).

I tried the following(not sure if this is the best way):

@receiver(pre_save, sender=YourModelName, weak=False, )
def presave_payment_model_check(sender, instance=None, created=False, **kwargs):
    #Reference: https://stackoverflow.com/questions/11561722/django-what-is-the-role-of-modelstate
    if instance._state.adding:
        # we would need to create the object
        print "Creating an object"
    else:
        #we are updating the object
        print "Updating an object"
    

Reference: Django : What is the role of ModelState?

Answered By: Pranaysharma

Using instance._state.adding is the most logical approach, as you will be able to tell the model state exists or is new, regardless whether the primary key as been assigned or not.

Answered By: Timothy Mugayi

You can easily check if an instance is created or updated in pre_save in this way:

@receiver(pre_save, sender=MyModel)
def pre_save_user(sender, instance, **kwargs): 
    if instance._state.adding:
        print ('Instance created!')
    else:
        print ('Instance updated!')

Tested with Django 3.0.

Answered By: Marco Ferrantini

You can try this.

@receiver(pre_save, sender=User)
def user(instance, *args, **kwargs):
    if instance.id != None:
Answered By: Sammrafi
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.