post_save is a Django ORM signal emitted after a model instance has been saved. It follows the observer pattern: register interest in a model action, then let a handler perform a side effect when that action occurs. section 6.5
The signal reports saves, not creates. A handler must inspect created to distinguish first-time creation from updates, and raw to avoid acting while a fixture is being loaded. The instance argument identifies the saved object. section 6.5
Create a profile after creating a user
from django.db.models.signals import post_save from django.dispatch import receiver @receiver(post_save, sender=User) def user_post_save(sender, **kwargs): if kwargs['created'] and not kwargs['raw']: user = kwargs['instance'] try: UserProfile.objects.get(user=user) except UserProfile.DoesNotExist: UserProfile.objects.create(user=user) The receiver runs after a User is saved, skips updates and fixture loads, checks that a profile does not already exist, and creates one only when necessary. section 6.5
A practical handler accounts for several creation paths:
- Application code can create the model. section 6.5
- Django Admin can create the model. section 6.5
- Fixture loading can create the model, so raw prevents the side effect. section 6.5
