base.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. from django.shortcuts import render
  2. from django.views.generic import View
  3. from misago.acl import add_acl
  4. from misago.core.shortcuts import get_object_or_404, validate_slug
  5. from misago.forums.models import Forum
  6. from misago.forums.permissions import allow_see_forum, allow_browse_forum
  7. from misago.threads.models import Thread, Post
  8. from misago.threads.permissions import allow_see_thread, allow_see_post
  9. __all__ = ['ForumMixin', 'ThreadMixin', 'PostMixin', 'ViewBase']
  10. class ForumMixin(object):
  11. """
  12. Mixin for getting forums
  13. """
  14. def get_forum(self, request, lock=False, **kwargs):
  15. forum = self.fetch_forum(request, lock, **kwargs)
  16. self.check_forum_permissions(request, forum)
  17. if kwargs.get('forum_slug'):
  18. validate_slug(forum, kwargs.get('forum_slug'))
  19. return forum
  20. def fetch_forum(self, request, lock=False, **kwargs):
  21. queryset = Forum.objects
  22. if lock:
  23. queryset = queryset.select_for_update()
  24. return get_object_or_404(
  25. queryset, id=kwargs.get('forum_id'), role='forum')
  26. def check_forum_permissions(self, request, forum):
  27. add_acl(request.user, forum)
  28. allow_see_forum(request.user, forum)
  29. allow_browse_forum(request.user, forum)
  30. class ThreadMixin(object):
  31. """
  32. Mixin for getting thread
  33. """
  34. def get_thread(self, request, lock=False, **kwargs):
  35. thread = self.fetch_thread(request, lock, **kwargs)
  36. self.check_forum_permissions(request, thread.forum)
  37. self.check_thread_permissions(request, thread)
  38. if kwargs.get('thread_slug'):
  39. validate_slug(thread, kwargs.get('thread_slug'))
  40. return thread
  41. def fetch_thread(self, request, lock=False, select_related=None,
  42. queryset=None, **kwargs):
  43. queryset = queryset or Thread.objects
  44. if lock:
  45. queryset = queryset.select_for_update()
  46. select_related = select_related or []
  47. if not 'forum' in select_related:
  48. select_related.append('forum')
  49. queryset = queryset.select_related(*select_related)
  50. where = {'id': kwargs.get('thread_id')}
  51. if 'forum_id' in kwargs:
  52. where['forum_id'] = kwargs.get('forum_id')
  53. return get_object_or_404(queryset, **where)
  54. def check_thread_permissions(self, request, thread):
  55. add_acl(request.user, thread)
  56. allow_see_thread(request.user, thread)
  57. class PostMixin(object):
  58. def get_post(self, request, lock=False, **kwargs):
  59. post = self.fetch_post(request, lock, **kwargs)
  60. post.thread.forum = post.forum
  61. self.check_forum_permissions(request, post.forum)
  62. self.check_thread_permissions(request, post.thread)
  63. self.check_post_permissions(request, post)
  64. return post
  65. def fetch_post(self, request, lock=False, select_related=None,
  66. queryset=None, **kwargs):
  67. queryset = queryset or Post.objects
  68. if lock:
  69. queryset = queryset.select_for_update()
  70. select_related = select_related or []
  71. if not 'forum' in select_related:
  72. select_related.append('forum')
  73. if not 'thread' in select_related:
  74. select_related.append('thread')
  75. queryset = queryset.select_related(*select_related)
  76. where = {'id': kwargs.get('post_id')}
  77. if 'thread_id' in kwargs:
  78. where['thread_id'] = kwargs.get('thread_id')
  79. if 'forum_id' in kwargs:
  80. where['forum_id'] = kwargs.get('forum_id')
  81. return get_object_or_404(queryset, **where)
  82. def check_post_permissions(self, request, post):
  83. add_acl(request.user, post)
  84. allow_see_post(request.user, post)
  85. class ViewBase(ForumMixin, ThreadMixin, PostMixin, View):
  86. def process_context(self, request, context):
  87. """
  88. Simple hook for extending and manipulating template context.
  89. """
  90. return context
  91. def render(self, request, context=None, template=None):
  92. context = self.process_context(request, context or {})
  93. template = template or self.template
  94. return render(request, template, context)