forked from rc/aircox
cfr #121 Co-authored-by: Christophe Siraut <d@tobald.eu.org> Co-authored-by: bkfox <thomas bkfox net> Co-authored-by: Thomas Kairos <thomas@bkfox.net> Reviewed-on: rc/aircox#131 Co-authored-by: Chris Tactic <ctactic@noreply.git.radiocampus.be> Co-committed-by: Chris Tactic <ctactic@noreply.git.radiocampus.be>
This commit is contained in:
@@ -1,72 +1,119 @@
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.http import HttpResponse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.views.generic.edit import CreateView, UpdateView
|
||||
from django.urls import reverse
|
||||
from honeypot.decorators import check_honeypot
|
||||
|
||||
from aircox.conf import settings
|
||||
from ..filters import PageFilters
|
||||
from ..forms import CommentForm
|
||||
from ..models import Comment
|
||||
from ..utils import Redirect
|
||||
from ..models import Comment, Category
|
||||
from .base import BaseView
|
||||
from .mixins import AttachedToMixin, FiltersMixin, ParentMixin
|
||||
|
||||
__all__ = [
|
||||
"attached_views",
|
||||
"attach",
|
||||
"BasePageListView",
|
||||
"BasePageDetailView",
|
||||
"PageDetailView",
|
||||
"PageListView",
|
||||
"PageUpdateView",
|
||||
]
|
||||
|
||||
|
||||
class BasePageListView(AttachedToMixin, ParentMixin, BaseView, ListView):
|
||||
attached_views = {}
|
||||
"""Register views by StaticPage.Target."""
|
||||
|
||||
|
||||
def attach(cls):
|
||||
"""Add decorated view class to `attached_views`"""
|
||||
attached_views[cls.attach_to_value] = cls
|
||||
return cls
|
||||
|
||||
|
||||
class BasePageMixin:
|
||||
category = None
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super().get_queryset().select_subclasses().select_related("cover")
|
||||
if self.request.user.is_authenticated:
|
||||
return qs
|
||||
return qs.published()
|
||||
|
||||
def get_category(self, page, **kwargs):
|
||||
if page:
|
||||
if getattr(page, "category_id", None):
|
||||
return page.category
|
||||
if getattr(page, "parent_id", None):
|
||||
return self.get_category(page.parent_subclass)
|
||||
if slug := self.kwargs.get("category_slug"):
|
||||
return Category.objects.get(slug=slug)
|
||||
return None
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
kwargs.setdefault("category", self.category)
|
||||
return super().get_context_data(*args, **kwargs)
|
||||
|
||||
|
||||
class BasePageListView(AttachedToMixin, BasePageMixin, ParentMixin, BaseView, ListView):
|
||||
"""Base view class for BasePage list."""
|
||||
|
||||
template_name = "aircox/basepage_list.html"
|
||||
item_template_name = "aircox/widgets/page_item.html"
|
||||
has_sidebar = True
|
||||
|
||||
paginate_by = 30
|
||||
has_headline = True
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
self.category = self.get_category(self.parent)
|
||||
return super().get(*args, **kwargs)
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().select_subclasses().published().select_related("cover")
|
||||
query = super().get_queryset()
|
||||
if self.category:
|
||||
query = query.filter(category=self.category)
|
||||
return query
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs.setdefault("item_template_name", self.item_template_name)
|
||||
kwargs.setdefault("has_headline", self.has_headline)
|
||||
return super().get_context_data(**kwargs)
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
parent = context.get("parent")
|
||||
if not context.get("page"):
|
||||
if not context.get("title"):
|
||||
model = self.model._meta.verbose_name_plural
|
||||
title = _("{model}")
|
||||
context["title"] = title.format(model=model, parent=parent)
|
||||
|
||||
if not context.get("cover") and parent and parent.cover:
|
||||
context["cover"] = parent.cover.url
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class BasePageDetailView(BaseView, DetailView):
|
||||
class BasePageDetailView(BasePageMixin, BaseView, DetailView):
|
||||
"""Base view class for BasePage."""
|
||||
|
||||
template_name = "aircox/basepage_detail.html"
|
||||
template_name = "aircox/public.html"
|
||||
context_object_name = "page"
|
||||
has_filters = False
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().select_related("cover")
|
||||
|
||||
# This should not exists: it allows mapping not published pages
|
||||
# or it should be only used for trashed pages.
|
||||
def not_published_redirect(self, page):
|
||||
"""When a page is not published, redirect to the returned url instead
|
||||
of an HTTP 404 code."""
|
||||
return None
|
||||
def get_context_data(self, **kwargs):
|
||||
if self.object.cover:
|
||||
kwargs.setdefault("cover", self.object.cover.url)
|
||||
if self.object.title:
|
||||
kwargs.setdefault("title", self.object.display_title)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def get_object(self):
|
||||
if getattr(self, "object", None):
|
||||
return self.object
|
||||
|
||||
obj = super().get_object()
|
||||
if not obj.is_published:
|
||||
redirect_url = self.not_published_redirect(obj)
|
||||
if redirect_url:
|
||||
raise Redirect(redirect_url)
|
||||
raise Http404("%s not found" % self.model._meta.verbose_name)
|
||||
self.category = self.get_category(obj)
|
||||
return obj
|
||||
|
||||
def get_page(self):
|
||||
@@ -78,7 +125,6 @@ class PageListView(FiltersMixin, BasePageListView):
|
||||
|
||||
filterset_class = PageFilters
|
||||
template_name = None
|
||||
has_filters = True
|
||||
categories = None
|
||||
filters = None
|
||||
|
||||
@@ -92,15 +138,21 @@ class PageListView(FiltersMixin, BasePageListView):
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super().get_queryset().select_related("category").order_by("-pub_date")
|
||||
cat_ids = self.model.objects.published().values_list("category_id", flat=True)
|
||||
self.categories = Category.objects.filter(id__in=cat_ids)
|
||||
return qs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs["categories"] = (
|
||||
self.model.objects.published()
|
||||
.filter(category__isnull=False)
|
||||
.values_list("category__title", "category__id")
|
||||
.distinct()
|
||||
@classmethod
|
||||
def get_secondary_nav(cls):
|
||||
cat_ids = cls.model.objects.published().values_list("category_id", flat=True)
|
||||
categories = Category.objects.filter(id__in=cat_ids)
|
||||
return tuple(
|
||||
(category.title, reverse(cls.model.list_url_name, kwargs={"category_slug": category.slug}))
|
||||
for category in categories
|
||||
)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs["categories"] = self.categories
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
@@ -109,7 +161,10 @@ class PageDetailView(BasePageDetailView):
|
||||
|
||||
template_name = None
|
||||
context_object_name = "page"
|
||||
has_filters = False
|
||||
|
||||
def can_edit(self, object):
|
||||
"""Return True if user can edit current page."""
|
||||
return False
|
||||
|
||||
def get_template_names(self):
|
||||
return super().get_template_names() + ["aircox/page_detail.html"]
|
||||
@@ -118,11 +173,26 @@ class PageDetailView(BasePageDetailView):
|
||||
return super().get_queryset().select_related("category")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
if self.object.allow_comments and "comment_form" not in kwargs:
|
||||
kwargs["comment_form"] = CommentForm()
|
||||
if "comment_form" not in kwargs:
|
||||
kwargs["comment_form"] = self.get_comment_form()
|
||||
kwargs["comments"] = Comment.objects.filter(page=self.object).order_by("-date")
|
||||
|
||||
if parent_subclass := getattr(self.object, "parent_subclass", None):
|
||||
kwargs["parent"] = parent_subclass
|
||||
|
||||
if "related_objects" not in kwargs:
|
||||
related = self.get_related_queryset()
|
||||
if related:
|
||||
related = related[: self.related_count]
|
||||
kwargs["related_objects"] = related
|
||||
kwargs["can_edit"] = self.can_edit(self.object)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def get_comment_form(self):
|
||||
if settings.ALLOW_COMMENTS and self.object.allow_comments:
|
||||
return CommentForm()
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def as_view(cls, *args, **kwargs):
|
||||
view = super(PageDetailView, cls).as_view(*args, **kwargs)
|
||||
@@ -138,3 +208,19 @@ class PageDetailView(BasePageDetailView):
|
||||
comment.page = self.object
|
||||
comment.save()
|
||||
return self.get(request, *args, **kwargs)
|
||||
|
||||
|
||||
class PageCreateView(BaseView, CreateView):
|
||||
def get_page(self):
|
||||
return self.object
|
||||
|
||||
def get_success_url(self):
|
||||
return self.request.path
|
||||
|
||||
|
||||
class PageUpdateView(BaseView, UpdateView):
|
||||
def get_page(self):
|
||||
return self.object
|
||||
|
||||
def get_success_url(self):
|
||||
return self.request.path
|
||||
|
||||
Reference in New Issue
Block a user