context_managers.py 1.7 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 netbox import thread_locals
  5. from netbox.request_context import set_request
  6. from .webhooks import flush_webhooks
  7. @contextmanager
  8. def change_logging(request):
  9. """
  10. Enable change logging by connecting the appropriate signals to their receivers before code is run, and
  11. disconnecting them afterward.
  12. :param request: WSGIRequest object with a unique `id` set
  13. """
  14. set_request(request)
  15. thread_locals.webhook_queue = []
  16. # Connect our receivers to the post_save and post_delete signals.
  17. post_save.connect(handle_changed_object, dispatch_uid='handle_changed_object')
  18. m2m_changed.connect(handle_changed_object, dispatch_uid='handle_changed_object')
  19. pre_delete.connect(handle_deleted_object, dispatch_uid='handle_deleted_object')
  20. clear_webhooks.connect(clear_webhook_queue, dispatch_uid='clear_webhook_queue')
  21. yield
  22. # Disconnect change logging signals. This is necessary to avoid recording any errant
  23. # changes during test cleanup.
  24. post_save.disconnect(handle_changed_object, dispatch_uid='handle_changed_object')
  25. m2m_changed.disconnect(handle_changed_object, dispatch_uid='handle_changed_object')
  26. pre_delete.disconnect(handle_deleted_object, dispatch_uid='handle_deleted_object')
  27. clear_webhooks.disconnect(clear_webhook_queue, dispatch_uid='clear_webhook_queue')
  28. # Flush queued webhooks to RQ
  29. flush_webhooks(thread_locals.webhook_queue)
  30. del thread_locals.webhook_queue
  31. # Clear the request from thread-local storage
  32. set_request(None)