aboutsummaryrefslogtreecommitdiff
path: root/apps/notes/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'apps/notes/views.py')
-rw-r--r--apps/notes/views.py154
1 files changed, 111 insertions, 43 deletions
diff --git a/apps/notes/views.py b/apps/notes/views.py
index 5d55720..6751340 100644
--- a/apps/notes/views.py
+++ b/apps/notes/views.py
@@ -1,6 +1,11 @@
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.views.generic.edit import FormView, ModelFormMixin
+from django.http import JsonResponse
+from django.core import serializers
+from django.forms import modelformset_factory
+from django.db.models import Count
+from django.views.generic.base import 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
@@ -14,10 +19,25 @@ from rest_framework import permissions
from .serializers import NoteSerializer, NotebookSerializer, NoteTagSerializer
from .models import Note, Notebook, LuxTag
from .forms import NoteForm, NotebookForm
+from utils.views import AjaxableResponseMixin
+
+##################
+# Base Views
+##################
+
+
+@method_decorator(login_required, name='dispatch')
+class BaseListView(ListView):
+ pass
+
+
+@method_decorator(login_required, name='dispatch')
+class BaseDetailView(DetailView):
+ pass
@method_decorator(login_required, name='dispatch')
-class LoggedInViewWithUser(View):
+class LoggedInViewWithUser(FormView):
def get_form_kwargs(self, **kwargs):
kwargs = super().get_form_kwargs(**kwargs)
@@ -25,12 +45,23 @@ class LoggedInViewWithUser(View):
return kwargs
-class NoteListView(LoggedInViewWithUser, ListView):
+##################
+# Note Views
+##################
+
+
+class NoteListView(BaseListView):
model = Note
def get_queryset(self):
if not self.request.user.is_anonymous:
- return Note.objects.filter(owner=self.request.user)
+ return Note.objects.prefetch_related('tags').filter(owner=self.request.user).select_related('notebook')
+
+ def get_context_data(self, **kwargs):
+ context = super(NoteListView, self).get_context_data(**kwargs)
+ context['notebook_list'] = Notebook.objects.filter(owner=self.request.user).exclude(name="Trash").annotate(note_count=Count('note'))
+ context['tag_list'] = LuxTag.objects.filter(note__owner=self.request.user).annotate(note_count=Count('note'))
+ return context
def get_template_names(self):
# print("IP Address for debug-toolbar: " + self.request.META['REMOTE_ADDR'])
@@ -40,36 +71,10 @@ class NoteListView(LoggedInViewWithUser, ListView):
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):
+class NoteDetailView(LoggedInViewWithUser, AjaxableResponseMixin, UpdateView):
+ '''
+ POST only works as AJAX
+ '''
model = Note
form_class = NoteForm
template_name = 'notes/notes_detail.html'
@@ -80,11 +85,20 @@ class NoteDetailView(UpdateView, LoggedInViewWithUser):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
- context['notes_list'] = Note.objects.filter(owner=self.request.user)
+ context['notebook_form'] = NotebookForm
return context
+ def form_valid(self, form):
+ self.object = form.save()
+ tags = serializers.serialize("json", self.object.tags.all())
+ data = {
+ 'tags': tags,
+ 'notebook': {'name': self.object.notebook.name, 'color': self.object.notebook.color_rgb}
+ }
+ return JsonResponse(data, safe=True)
+
-class NoteCreateView(CreateView, LoggedInViewWithUser):
+class NoteCreateView(LoggedInViewWithUser, CreateView):
model = Note
form_class = NoteForm
template_name = 'notes/notes_create.html'
@@ -99,27 +113,76 @@ class NoteCreateView(CreateView, LoggedInViewWithUser):
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['notebook_form'] = NotebookForm
+ # context['notes_list'] = Note.objects.filter(owner=self.request.user).select_related()
+ return context
+
+
+class NoteTagView(BaseListView):
+ 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:
+ try:
+ tags = self.kwargs['slug'].split("+")
+ except ValueError:
+ tags = self.kwargs['slug']
+ self.tag_list = [x.strip() for x in tags]
+ qs = Note.objects.prefetch_related('tags').filter(owner=self.request.user).select_related('notebook')
+ 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'] = LuxTag.objects.filter(slug__in=self.tag_list)
return context
-class NotebookListView(CreateView, LoggedInViewWithUser):
+##################
+# Notebook Views
+##################
+
+
+class NotebookListView(LoggedInViewWithUser, CreateView):
model = Notebook
form_class = NotebookForm
- template_name = 'notes/notebook_create.html'
+ template_name = 'notes/notebook_list.html'
def get_queryset(self):
if not self.request.user.is_anonymous:
return Notebook.objects.filter(owner=self.request.user)
+ def form_valid(self, form):
+ form.instance.owner = self.request.user
+ self.object = form.save()
+ return super(NotebookListView, self).form_valid(form)
+
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()
+ NotebookFormSet = modelformset_factory(Notebook, form=NotebookForm, extra=0)
+ context['notebook_form_list'] = NotebookFormSet(queryset=Notebook.objects.filter(owner=self.request.user).exclude(name="Trash").select_related().annotate(note_count=Count('note')))
+ #context['notebook_list'] = Notebook.objects.filter(owner=self.request.user).exclude(name="Trash").select_related().annotate(note_count=Count('note'))
+ #context['notes_list'] = Note.objects.filter(owner=self.request.user).select_related()
return context
+ def get_success_url(self):
+ return reverse_lazy('notebooks:detail', kwargs={'slug': self.object.slug})
+
-class NotebookDetailView(DetailView, LoggedInViewWithUser):
+class NotebookDetailView(BaseDetailView):
model = Notebook
def get_object(self):
@@ -129,11 +192,16 @@ class NotebookDetailView(DetailView, LoggedInViewWithUser):
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['notes_list'] = Note.objects.filter(owner=self.request.user).select_related()
context['form'] = self.form
return context
+##################
+# API Views
+##################
+
+
class IsOwnerOrDeny(permissions.BasePermission):
"""
Custom permission to only allow owners to post to their endpoint