fallback.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. from django.contrib.messages.storage.base import BaseStorage
  2. from django.contrib.messages.storage.cookie import CookieStorage
  3. from django.contrib.messages.storage.session import SessionStorage
  4. try:
  5. set
  6. except NameError:
  7. from sets import Set as set # Python 2.3
  8. class FallbackStorage(BaseStorage):
  9. """
  10. Tries to store all messages in the first backend, storing any unstored
  11. messages in each subsequent backend backend.
  12. """
  13. storage_classes = (CookieStorage, SessionStorage)
  14. def __init__(self, *args, **kwargs):
  15. super(FallbackStorage, self).__init__(*args, **kwargs)
  16. self.storages = [storage_class(*args, **kwargs)
  17. for storage_class in self.storage_classes]
  18. self._used_storages = set()
  19. def _get(self, *args, **kwargs):
  20. """
  21. Gets a single list of messages from all storage backends.
  22. """
  23. all_messages = []
  24. for storage in self.storages:
  25. messages, all_retrieved = storage._get()
  26. # If the backend hasn't been used, no more retrieval is necessary.
  27. if messages is None:
  28. break
  29. if messages:
  30. self._used_storages.add(storage)
  31. all_messages.extend(messages)
  32. # If this storage class contained all the messages, no further
  33. # retrieval is necessary
  34. if all_retrieved:
  35. break
  36. return all_messages, all_retrieved
  37. def _store(self, messages, response, *args, **kwargs):
  38. """
  39. Stores the messages, returning any unstored messages after trying all
  40. backends.
  41. For each storage backend, any messages not stored are passed on to the
  42. next backend.
  43. """
  44. for storage in self.storages:
  45. if messages:
  46. messages = storage._store(messages, response,
  47. remove_oldest=False)
  48. # Even if there are no more messages, continue iterating to ensure
  49. # storages which contained messages are flushed.
  50. elif storage in self._used_storages:
  51. storage._store([], response)
  52. self._used_storages.remove(storage)
  53. return messages