Last active
December 12, 2020 09:10
-
-
Save AndrewIngram/a37842abd220e5e998525953b9510179 to your computer and use it in GitHub Desktop.
Django one-off on_save callbacks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import transaction | |
from django.db import models | |
from django.db.models.signals import post_save | |
def on_save(obj: models.Model, callback, on_commit=False): | |
""" | |
Attaches a one-off callback that's triggered after a Django model instance is | |
saved. Optionally makes use of transaction.on_commit to defer until any wrapping | |
transaction has also committed. | |
This lets us build up a queue of side-effects to get triggered after some changes | |
are saved to the database, but crucially in a way such that the side-effects aren't | |
triggered if the save fails for some reason. | |
Usage: | |
on_save(my_instance, lambda: track_event('Something happened')) | |
on_save(my_instance, lambda: track_event('Something happened'), on_commit=True) | |
""" | |
def receiver(sender, instance, using, **kwargs): | |
if instance == obj: | |
if on_commit: | |
transaction.on_commit(callback, using=using) | |
else: | |
callback() | |
post_save.disconnect(receiver) | |
post_save.connect(receiver, sender=type(obj)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment