Created
December 10, 2021 11:43
-
-
Save AndrewIngram/471d7bb214a2c0f276234573eddbe9a4 to your computer and use it in GitHub Desktop.
Django on_save callback
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
import logging | |
from django.db import models, transaction | |
from django.db.models.signals import post_save | |
logger = logging.getLogger(__name__) | |
def on_save(obj: models.Model, callback): | |
""" | |
Attaches a one-off callback that's triggered after a Django model instance is | |
saved. | |
""" | |
dispatch_uid = f"model_on_save_{id(callback)}" | |
def receiver(sender, instance, using, **kwargs): | |
if instance == obj: | |
try: | |
# Disconnect early so that any saves inside the callback don't | |
# trigger a nasty loop | |
post_save.disconnect( | |
receiver, sender=type(obj), dispatch_uid=dispatch_uid | |
) | |
transaction.on_commit(callback, using=using) | |
except Exception: | |
logger.exception("on_save callback failed for %s", str(instance)) | |
post_save.connect( | |
receiver, | |
sender=type(obj), | |
weak=False, | |
dispatch_uid=dispatch_uid, | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment