views.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. from django.conf import settings
  2. from django.contrib.auth.mixins import LoginRequiredMixin
  3. from django.shortcuts import get_object_or_404
  4. from django.urls import reverse
  5. from django.views import generic
  6. from .forms import CommentForm
  7. from .models import Comment, News
  8. class NewsList(generic.ListView):
  9. """Список новостей."""
  10. model = News
  11. template_name = 'news/home.html'
  12. def get_queryset(self):
  13. """
  14. Выводим только несколько последних новостей.
  15. Их количество определяется в настройках проекта.
  16. """
  17. return self.model.objects.prefetch_related(
  18. 'comment_set'
  19. )[:settings.NEWS_COUNT_ON_HOME_PAGE]
  20. class NewsDetail(generic.DetailView):
  21. model = News
  22. template_name = 'news/detail.html'
  23. def get_object(self, queryset=None):
  24. obj = get_object_or_404(
  25. self.model.objects.prefetch_related('comment_set__author'),
  26. pk=self.kwargs['pk']
  27. )
  28. return obj
  29. def get_context_data(self, **kwargs):
  30. context = super().get_context_data(**kwargs)
  31. if self.request.user.is_authenticated:
  32. context['form'] = CommentForm()
  33. return context
  34. class NewsComment(
  35. LoginRequiredMixin,
  36. generic.detail.SingleObjectMixin,
  37. generic.FormView
  38. ):
  39. model = News
  40. form_class = CommentForm
  41. template_name = 'news/detail.html'
  42. def post(self, request, *args, **kwargs):
  43. self.object = self.get_object()
  44. return super().post(request, *args, **kwargs)
  45. def form_valid(self, form):
  46. comment = form.save(commit=False)
  47. comment.news = self.object
  48. comment.author = self.request.user
  49. comment.save()
  50. return super().form_valid(form)
  51. def get_success_url(self):
  52. post = self.get_object()
  53. return reverse('news:detail', kwargs={'pk': post.pk}) + '#comments'
  54. class NewsDetailView(generic.View):
  55. def get(self, request, *args, **kwargs):
  56. view = NewsDetail.as_view()
  57. return view(request, *args, **kwargs)
  58. def post(self, request, *args, **kwargs):
  59. view = NewsComment.as_view()
  60. return view(request, *args, **kwargs)
  61. class CommentBase(LoginRequiredMixin):
  62. """Базовый класс для работы с комментариями."""
  63. model = Comment
  64. def get_success_url(self):
  65. comment = self.get_object()
  66. return reverse(
  67. 'news:detail', kwargs={'pk': comment.news.pk}
  68. ) + '#comments'
  69. def get_queryset(self):
  70. """Пользователь может работать только со своими комментариями."""
  71. return self.model.objects.filter(author=self.request.user)
  72. class CommentUpdate(CommentBase, generic.UpdateView):
  73. """Редактирование комментария."""
  74. template_name = 'news/edit.html'
  75. form_class = CommentForm
  76. class CommentDelete(CommentBase, generic.DeleteView):
  77. """Удаление комментария."""
  78. template_name = 'news/delete.html'