from django.http import HttpResponseRedirect, HttpResponseBadRequest, HttpResponseForbidden from django.views import generic from django.views.decorators.http import require_http_methods, require_safe, require_POST from django.urls import reverse from django.shortcuts import get_object_or_404, render from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from rest_framework import viewsets, permissions from rest_framework.decorators import action from . import serializers, models class MovieViewSet(viewsets.ModelViewSet): queryset = models.Movie.objects.order_by('id').all() serializer_class = serializers.MovieSerializer permission_classes = [permissions.IsAuthenticatedOrReadOnly] def perform_create(self, serializer): serializer.save(owner=self.request.user) # @action(detail=True, methods=["POST"]) # def vote(self, request, pk=None): # movie = self.get_object() # vote = request.date.get("vote", 0) class IndexView(generic.ListView): template_name = "watchlist/index.html" model = models.Movie def get_queryset(self): qs = models.Movie.objects # Filter if self.request.GET.get("watched", False) != "true": qs = qs.filter(watched=False) # Sort order = self.request.GET.get("sort", "score") if order in ('id', '-id', 'name', '-name'): qs = qs.order_by(order).all() elif order == "score" or order == "-score": qs = sorted(qs.all(), key=lambda x: x.score, reverse=True if order == "score" else False) return qs def get_context_data(self): context = super().get_context_data() context['can_add_movie'] = self.request.user.has_perm("watchlist.add_movie") context['voted_movies'] = models.Movie.objects.filter(movievote__user=self.request.user) return context class DetailView(generic.DetailView): model = models.Movie def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) votes = self.object.movievote_set.all() user_vote = None if self.request.user.is_authenticated: user_vote = votes.filter(user=self.request.user).first() context["votes"] = votes context["user_vote"] = user_vote return context @login_required @require_POST def vote(request, pk): movie = get_object_or_404(models.Movie, pk=pk) user_vote = movie.movievote_set.filter(user=request.user).first() if user_vote is None: user_vote = models.MovieVote(movie=movie, user=request.user) user_vote.vote = request.POST['vote'] user_vote.seen = request.POST.get('seen', False) == "on" user_vote.save() return HttpResponseRedirect(reverse('watchlist:index')) class EditView(generic.DetailView): model = models.Movie template_name = "watchlist/edit.html" def can_edit_movie(self, request): return request.user.has_perm('watchlist.moderate_movies') or request.user == self.object.suggested_by def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["users"] = User.objects.all() if self.request.user.has_perm("watchlist.moderate_movies") else None return context def get(self, request, *args, **kwargs): self.object = self.get_object() if not self.can_edit_movie(request): return HttpResponseForbidden("You cannot edit this object.") return super().get(request, *args, **kwargs) def post(self, request, *args, **kwargs): self.object = self.get_object() if not self.can_edit_movie(request): return HttpResponseForbidden("You cannot edit this object.") if "name" in request.POST: self.object.name = request.POST["name"] if "suggested_by" in request.POST: if request.user.has_perm('watchlist.moderate_movies'): new_suggestor = User.objects.filter(username=request.POST["suggested_by"]).first() if new_suggestor is None: return HttpResponseBadRequest("The new suggestor doesn't exist.") self.object.suggested_by = new_suggestor # else: # if request.POST["suggested_by"] != self.object.suggested_by.username: # return HttpResponseForbidden("You cannot change the suggested by field.") self.object.save() return HttpResponseRedirect(reverse('watchlist:detail', args=(kwargs["pk"],))) @login_required @require_POST def submit(request): if not request.user.has_perm("watchlist.add_movie"): return HttpResponseForbidden("You can't add new movies.") movie = models.Movie(name=request.POST["name"], suggested_by=request.user, watched=False) movie.save() return HttpResponseRedirect(reverse("watchlist:index")) @login_required @require_POST def delete(request, pk): movie = get_object_or_404(models.Movie, pk=pk) if not (request.user.has_perm("watchlist.moderate_movies") or ( request.user.has_perm("watchlist.delete_movie") and request.user == movie.suggested_by )): return HttpResponseForbidden("You can't delete this movie") movie.delete() return HttpResponseRedirect(reverse("watchlist:index"))