mixins.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
  2. # Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
  3. # Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU Affero General Public License as
  6. # published by the Free Software Foundation, either version 3 of the
  7. # License, or (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU Affero General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. import warnings
  17. from .services import take_snapshot
  18. class HistoryResourceMixin(object):
  19. """
  20. Rest Framework resource mixin for resources
  21. susceptible to have models with history.
  22. """
  23. # This attribute will store the last history entry
  24. # created for this resource. It is mainly used for
  25. # notifications mixin.
  26. __last_history = None
  27. __object_saved = False
  28. def get_last_history(self):
  29. if not self.__object_saved:
  30. message = ("get_last_history() function called before any object are saved. "
  31. "Seems you have a wrong mixing order on your resource.")
  32. warnings.warn(message, RuntimeWarning)
  33. return self.__last_history
  34. def get_object_for_snapshot(self, obj):
  35. """
  36. Method that returns a model instance ready to snapshot.
  37. It is by default noop, but should be overwrited when
  38. snapshot ready instance is found in one of foreign key
  39. fields.
  40. """
  41. return obj
  42. def persist_history_snapshot(self, obj=None, delete:bool=False):
  43. """
  44. Shortcut for resources with special save/persist
  45. logic.
  46. """
  47. user = self.request.user
  48. comment = self.request.DATA.get("comment", "")
  49. if obj is None:
  50. obj = self.get_object()
  51. sobj = self.get_object_for_snapshot(obj)
  52. if sobj != obj and delete:
  53. delete = False
  54. self.__last_history = take_snapshot(sobj, comment=comment, user=user, delete=delete)
  55. self.__object_saved = True
  56. def post_save(self, obj, created=False):
  57. self.persist_history_snapshot(obj=obj)
  58. super().post_save(obj, created=created)
  59. def pre_delete(self, obj):
  60. self.persist_history_snapshot(obj, delete=True)
  61. super().pre_delete(obj)