from django.views.generic import CreateView, ListView, UpdateView, DeleteView from django.views.generic.detail import DetailView from django.views.generic.base import View, RedirectView from django.utils.decorators import method_decorator from django.contrib.auth.decorators import login_required from django.shortcuts import get_object_or_404, render, redirect from django.urls import reverse, reverse_lazy from rest_framework import viewsets from rest_framework.response import Response from rest_framework.decorators import list_route from rest_framework import permissions from .serializers import NoteSerializer, NotebookSerializer, NoteTagSerializer from .models import Note, Notebook, LuxTag from .forms import NoteForm, NotebookForm @method_decorator(login_required, name='dispatch') class LoggedInViewWithUser(View): def get_form_kwargs(self, **kwargs): kwargs = super().get_form_kwargs(**kwargs) kwargs.update({'user': self.request.user}) return kwargs class NoteListView(LoggedInViewWithUser, ListView): model = Note def get_queryset(self): if not self.request.user.is_anonymous: return Note.objects.filter(owner=self.request.user) def get_template_names(self): # print("IP Address for debug-toolbar: " + self.request.META['REMOTE_ADDR']) if not self.request.user.is_anonymous: return ['notes/notes_list.html'] else: return ['sell.html'] class NoteTagView(LoggedInViewWithUser, ListView): model = Note template_name = 'notes/notes_list.html' def get_queryset(self): ''' This can generate a crazy amount of joins if there's a lot of tags have to keep an eye on it. Would be better to do: from django.db.models import Q from functools import reduce from operator import and_, or_ #query = reduce(and_, (Q(tags__slug=t) for t in self.tag_list)) # Note.objects.filter(query, owner=self.request.user) But that doesn't work for some reason. ''' if not self.request.user.is_anonymous: self.tag_list = [x.strip() for x in self.kwargs['slug'].split("+")] qs = Note.objects.filter(owner=self.request.user) for tag in self.tag_list: qs = qs.filter(tags__slug=tag) return qs def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['notes_list'] = Note.objects.filter(owner=self.request.user) context['tags'] = self.tag_list return context class NoteDetailView(UpdateView, LoggedInViewWithUser): model = Note form_class = NoteForm template_name = 'notes/notes_detail.html' def get_queryset(self): if not self.request.user.is_anonymous: return Note.objects.filter(owner=self.request.user) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['notes_list'] = Note.objects.filter(owner=self.request.user) return context class NoteCreateView(CreateView, LoggedInViewWithUser): model = Note form_class = NoteForm template_name = 'notes/notes_create.html' def form_valid(self, form): form.instance.owner = self.request.user self.object = form.save() return super(NoteCreateView, self).form_valid(form) def get_success_url(self): return reverse_lazy('notes:detail', kwargs={'slug': self.object.slug, 'pk': self.object.pk}) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['notes_list'] = Note.objects.filter(owner=self.request.user).select_related() return context class NotebookListView(CreateView, LoggedInViewWithUser): model = Notebook form_class = NotebookForm template_name = 'notes/notebook_create.html' def get_queryset(self): if not self.request.user.is_anonymous: return Notebook.objects.filter(owner=self.request.user) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['notebook_list'] = Notebook.objects.filter(owner=self.request.user) context['notes_list'] = Note.objects.filter(owner=self.request.user).select_related() return context class NotebookDetailView(DetailView, LoggedInViewWithUser): model = Notebook def get_object(self): notebook = get_object_or_404(self.get_queryset().select_related(), owner=self.request.user, slug=self.kwargs["slug"]) self.form = NotebookForm(instance=notebook) return notebook def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['notes_list'] = Note.objects.filter(owner=self.request.user).select_related() context['form'] = self.form return context class IsOwnerOrDeny(permissions.BasePermission): """ Custom permission to only allow owners to post to their endpoint """ def has_object_permission(self, request, view, obj): # Write permissions are only allowed to the owner of the snippet. return obj.owner == request.user class NoteViewSet(viewsets.ModelViewSet): """ API endpoint that allows notes to be viewed or edited. """ serializer_class = NoteSerializer permission_classes = (permissions.IsAuthenticated,) def get_queryset(self): return Note.objects.filter(owner=self.request.user).order_by('-date_created') def perform_create(self, serializer): serializer.save(owner=self.request.user, tags__owner=self.request.user) def get_object(self): obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"]) if obj.is_public: return obj else: self.check_object_permissions(self.request, obj) return obj class NotebookViewSet(viewsets.ModelViewSet): """ API endpoint that allows botebook to be viewed or edited. """ serializer_class = NotebookSerializer def get_queryset(self): return Notebook.objects.filter(owner=self.request.user).order_by('-date_created') def perform_create(self, serializer): serializer.save(owner=self.request.user) def get_menu_data(self, serializer): return Notebook.objects.filter(owner=self.request.user).order_by('-name')[:1] class TagViewSet(viewsets.ModelViewSet): """ API endpoint that allows notes to be viewed or edited. """ serializer_class = NoteTagSerializer permission_classes = (permissions.IsAuthenticated,) def get_queryset(self): return LuxTag.objects.filter(owner=self.request.user) def perform_create(self, serializer): serializer.save(owner=self.request.user)