context_managers.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. from contextlib import contextmanager
  2. from django.db.models.signals import m2m_changed, pre_delete, post_save
  3. from extras.signals import clear_webhooks, _clear_webhook_queue, _handle_changed_object, _handle_deleted_object
  4. from utilities.utils import curry
  5. from .webhooks import flush_webhooks
  6. @contextmanager
  7. def change_logging(request):
  8. """
  9. Enable change logging by connecting the appropriate signals to their receivers before code is run, and
  10. disconnecting them afterward.
  11. :param request: WSGIRequest object with a unique `id` set
  12. """
  13. webhook_queue = []
  14. # Curry signals receivers to pass the current request
  15. handle_changed_object = curry(_handle_changed_object, request, webhook_queue)
  16. handle_deleted_object = curry(_handle_deleted_object, request, webhook_queue)
  17. clear_webhook_queue = curry(_clear_webhook_queue, webhook_queue)
  18. # Connect our receivers to the post_save and post_delete signals.
  19. post_save.connect(handle_changed_object, dispatch_uid='handle_changed_object')
  20. m2m_changed.connect(handle_changed_object, dispatch_uid='handle_changed_object')
  21. pre_delete.connect(handle_deleted_object, dispatch_uid='handle_deleted_object')
  22. clear_webhooks.connect(clear_webhook_queue, dispatch_uid='clear_webhook_queue')
  23. yield
  24. # Disconnect change logging signals. This is necessary to avoid recording any errant
  25. # changes during test cleanup.
  26. post_save.disconnect(handle_changed_object, dispatch_uid='handle_changed_object')
  27. m2m_changed.disconnect(handle_changed_object, dispatch_uid='handle_changed_object')
  28. pre_delete.disconnect(handle_deleted_object, dispatch_uid='handle_deleted_object')
  29. clear_webhooks.disconnect(clear_webhook_queue, dispatch_uid='clear_webhook_queue')
  30. # Flush queued webhooks to RQ
  31. flush_webhooks(webhook_queue)
  32. del webhook_queue