django_transaction_signals

Adds post_commit and post_rollback signal handlers to Django
Download

django_transaction_signals Ranking & Summary

Advertisement

  • Rating:
  • License:
  • Other/Proprietary Li...
  • Price:
  • FREE
  • Publisher Name:
  • David Hughes
  • Publisher web site:
  • https://github.com/davehughes/

django_transaction_signals Tags


django_transaction_signals Description

While working on the ASU Digital Repository, I found I needed the ability to trigger callbacks when a transaction was committed. Django's signals seemed to be the perfect mechanism, but transaction commit and rollback signals are not (as of this writing) supported in the core framework. (See these tickets in the Django issue tracker for background: Ticket #14050, Ticket #14051)However, a gist written by Grégoire Cachet seems to do the trick. It adds a custom signal implementation and monkey-patches Django's transaction handling functions to dispatch post_commit and post_rollback signals.django_transaction_signals is a Django app that extends that gist in the following ways:- Adds a defer() function that can be used inside a transaction to defer the execution of a function until the transaction has committed (I found this quite useful for triggering Celery tasks that depend on the objects committed).- Guards against badly behaved signal handlers (i.e. ones that leave the current transaction in a dirty state) and raises a BadlyBehavedTransactionSignalHandlerError when it detects a misbehaving handler.- Clears handlers on transaction exit regardless of whether a commit, rollback, or neither occurred. This fixes an issue where handlers could accumulate and be triggered on a subsequent transaction.Usage (from the original gist):You have to make sure to load this before you use signals.For example, add the the following line to your project's __init__.py file:import django_transaction_signalsThen, to use the signals, create a function and bind it to the post_commit signal:from django.db import transactiondef my_function(**kwargs): # do your stuff here passtransaction.signals.post_commit.connect(my_function)If you're using non-local variables in your callback function, make sure to use non-weak reference or your variables could be garbage collected before the function gets called. For example, in a model's save() method:def save(self, *args, **kwargs): def my_function(**kwargs): # do your stuff here # access self variable self transaction.signals.post_commit.connect(my_function, weak=False)Usage of defer() function:defer() registers a function to be run upon successful completion of the current transaction (if one exists). Calling defer(func, *args, **kwargs) translates to the following:- If a transaction is active, register a post-commit listener to execute func(*args, **kwargs)- If no transaction is active, execute func(*args, **kwargs) immediatelyThis example demonstrates a transactional update of a model object which registers a Celery task to be executed when the transaction commits successfully.from celery.task import taskfrom django.db import transactionfrom django_transaction_signals import deferimport pysolr@transaction.commit_on_successdef update_object(obj): # ...modify and save object... defer(index_object.delay, obj) # ...do some additional work in the transaction...@taskdef index_object(obj): index_obj = {'id': obj.id} # ...build index object... solr = pysolr.Solr('http://localhost:8080/solr') solr.add()Product's homepage


django_transaction_signals Related Software