What is the canonical way to find out if a Django model is saved to db?

Nowadays you can check for:

self._state.adding

This value is set by the QuerySet.iterator() for objects which are not added yet in the database. You can't use this value in the __init__() method yet, as it's set after the object is constructed.


Important Note (as of 6 May '19): If your models use UUID fields (or other method of internal ID generation, use self._state.adding as mentioned in the comments.

Actually,obj.pk is the most canonical way. Django itself often doesn't "know" if the object is saved or not. According to the django model instance reference, if there is a primary key set already, it checks onsave() calls by selecting for the id in the database before any insert.

Even if you set user = models.OneToOneField(..., primary_key=True) the .pk attribute will still point to the correct primary key (most likely user_id) and you can use it and set it as if it was the same property.

If you want to know after an object has been saved, you can catch the post_save signal. This signal is fired on model saves, and if you want you can add your own application-specific attribute to the model, for example obj.was_saved = True. I think django avoids this to keep their instances clean, but there's no real reason why you couldn't do this for yourself. Here is a minimal example:

from django.db.models.signals import post_save
from myapp.models import MyModel

def save_handler(sender, instance, **kwargs):
    instance.was_saved = True

post_save.connect(save_handler, sender=MyModel)

You can alternately have this function work for all models in your app by simply connecting the signal without specifying the sender= argument. Beware though, you can create undefined behaviours if you override a property on someone else's model instance that you are importing.