threadpoll.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. from django.db import transaction
  2. from django.http import Http404
  3. from rest_framework import viewsets
  4. from rest_framework.decorators import detail_route, list_route
  5. from rest_framework.response import Response
  6. from misago.acl import add_acl
  7. from misago.core.shortcuts import get_int_or_404
  8. from ..models import Poll, PollVote
  9. from ..permissions.polls import (
  10. allow_start_poll, allow_edit_poll, allow_delete_poll, can_start_poll)
  11. from ..serializers import PollSerializer, NewPollSerializer, EditPollSerializer
  12. from ..viewmodels.thread import ForumThread
  13. class ViewSet(viewsets.ViewSet):
  14. thread = None
  15. def get_thread(self, request, thread_pk, select_for_update=False):
  16. return self.thread(
  17. request,
  18. get_int_or_404(thread_pk),
  19. select_for_update=select_for_update,
  20. ).model
  21. def get_thread_for_update(self, request, thread_pk):
  22. return self.get_thread(request, thread_pk, select_for_update=True)
  23. def get_poll(self, thread, pk):
  24. try:
  25. poll_id = get_int_or_404(pk)
  26. if thread.poll.pk != poll_id:
  27. raise Http404()
  28. poll = Poll.objects.select_for_update().get(pk=thread.poll.pk)
  29. poll.thread = thread
  30. poll.category = thread.category
  31. return poll
  32. except Poll.DoesNotExist:
  33. raise Http404()
  34. @transaction.atomic
  35. def create(self, request, thread_pk):
  36. thread = self.get_thread_for_update(request, thread_pk)
  37. allow_start_poll(request.user, thread)
  38. instance = Poll(
  39. thread=thread,
  40. category=thread.category,
  41. poster=request.user,
  42. poster_name=request.user.username,
  43. poster_slug=request.user.slug,
  44. poster_ip=request.user_ip,
  45. )
  46. serializer = NewPollSerializer(instance, data=request.data)
  47. if serializer.is_valid():
  48. serializer.save()
  49. add_acl(request.user, instance)
  50. return Response(PollSerializer(instance).data)
  51. else:
  52. return Response(serializer.errors, status=400)
  53. @transaction.atomic
  54. def update(self, request, thread_pk, pk):
  55. thread = self.get_thread(request, thread_pk)
  56. instance = self.get_poll(thread, pk)
  57. allow_edit_poll(request.user, instance)
  58. serializer = EditPollSerializer(instance, data=request.data)
  59. if serializer.is_valid():
  60. serializer.save()
  61. add_acl(request.user, instance)
  62. serialized_poll = PollSerializer(instance).data
  63. instance.make_choices_votes_aware(request.user, serialized_poll['choices'])
  64. return Response(serialized_poll)
  65. else:
  66. return Response(serializer.errors, status=400)
  67. @transaction.atomic
  68. def delete(self, request, thread_pk, pk):
  69. thread = self.get_thread(request, thread_pk)
  70. instance = self.get_poll(thread, pk)
  71. allow_delete_poll(request.user, instance)
  72. thread.poll.delete()
  73. return Response({
  74. 'can_start_poll': can_start_poll(request.user, thread)
  75. })
  76. class ThreadPollViewSet(ViewSet):
  77. thread = ForumThread