category.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from django.core.exceptions import PermissionDenied
  2. from django.utils.translation import gettext as _
  3. from django.utils.translation import gettext_lazy
  4. from rest_framework import serializers
  5. from . import PostingEndpoint, PostingMiddleware
  6. from ....acl.objectacl import add_acl_to_obj
  7. from ....categories import THREADS_ROOT_NAME
  8. from ....categories.models import Category
  9. from ....categories.permissions import can_browse_category, can_see_category
  10. from ...permissions import allow_start_thread
  11. from ...threadtypes import trees_map
  12. class CategoryMiddleware(PostingMiddleware):
  13. """
  14. middleware that validates category id and sets category on thread and post instances
  15. """
  16. def use_this_middleware(self):
  17. if self.mode == PostingEndpoint.START:
  18. return self.tree_name == THREADS_ROOT_NAME
  19. return False
  20. def get_serializer(self):
  21. return CategorySerializer(self.user_acl, data=self.request.data)
  22. def pre_save(self, serializer):
  23. category = serializer.category_cache
  24. add_acl_to_obj(self.user_acl, category)
  25. # set flags for savechanges middleware
  26. category.update_all = False
  27. category.update_fields = []
  28. # assign category to thread and post
  29. self.thread.category = category
  30. self.post.category = category
  31. class CategorySerializer(serializers.Serializer):
  32. category = serializers.IntegerField(
  33. error_messages={
  34. "required": gettext_lazy("You have to select category to post thread in."),
  35. "invalid": gettext_lazy("Selected category is invalid."),
  36. }
  37. )
  38. def __init__(self, user_acl, *args, **kwargs):
  39. self.user_acl = user_acl
  40. self.category_cache = None
  41. super().__init__(*args, **kwargs)
  42. def validate_category(self, value):
  43. try:
  44. self.category_cache = Category.objects.get(
  45. pk=value, tree_id=trees_map.get_tree_id_for_root(THREADS_ROOT_NAME)
  46. )
  47. can_see = can_see_category(self.user_acl, self.category_cache)
  48. can_browse = can_browse_category(self.user_acl, self.category_cache)
  49. if not (self.category_cache.level and can_see and can_browse):
  50. raise PermissionDenied(_("Selected category is invalid."))
  51. allow_start_thread(self.user_acl, self.category_cache)
  52. except Category.DoesNotExist:
  53. raise serializers.ValidationError(
  54. _(
  55. "Selected category doesn't exist or "
  56. "you don't have permission to browse it."
  57. )
  58. )
  59. except PermissionDenied as e:
  60. raise serializers.ValidationError(e.args[0])