aircox/aircox/views/page.py
2023-03-13 17:47:00 +01:00

154 lines
4.6 KiB
Python

from django.http import Http404, HttpResponse
from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView
from honeypot.decorators import check_honeypot
from ..filters import PageFilters
from ..forms import CommentForm
from ..models import Comment
from ..utils import Redirect
from .base import BaseView
from .mixins import AttachedToMixin, FiltersMixin, ParentMixin
__all__ = [
"BasePageListView",
"BasePageDetailView",
"PageDetailView",
"PageListView",
]
class BasePageListView(AttachedToMixin, 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 get(self, *args, **kwargs):
return super().get(*args, **kwargs)
def get_queryset(self):
return (
super()
.get_queryset()
.select_subclasses()
.published()
.select_related("cover")
)
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)
class BasePageDetailView(BaseView, DetailView):
"""Base view class for BasePage."""
template_name = "aircox/basepage_detail.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_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)
return obj
def get_page(self):
return self.object
class PageListView(FiltersMixin, BasePageListView):
"""Page list view."""
filterset_class = PageFilters
template_name = None
has_filters = True
categories = None
filters = None
def get_template_names(self):
return super().get_template_names() + ["aircox/page_list.html"]
def get_filterset(self, data, query):
# FIXME: not the most efficient, cause join then split (django filters)
data["category__id__in"] = ",".join(data.getlist("category__id__in"))
return super().get_filterset(data, query)
def get_queryset(self):
qs = (
super()
.get_queryset()
.select_related("category")
.order_by("-pub_date")
)
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()
)
return super().get_context_data(**kwargs)
class PageDetailView(BasePageDetailView):
"""Base view class for pages."""
template_name = None
context_object_name = "page"
has_filters = False
def get_template_names(self):
return super().get_template_names() + ["aircox/page_detail.html"]
def get_queryset(self):
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()
kwargs["comments"] = Comment.objects.filter(page=self.object).order_by(
"-date"
)
return super().get_context_data(**kwargs)
@classmethod
def as_view(cls, *args, **kwargs):
view = super(PageDetailView, cls).as_view(*args, **kwargs)
return check_honeypot(view, field_name="website")
def post(self, request, *args, **kwargs):
self.object = self.get_object()
if not self.object.allow_comments:
return HttpResponse(_("comments are not allowed"), status=503)
form = CommentForm(request.POST)
comment = form.save(commit=False)
comment.page = self.object
comment.save()
return self.get(request, *args, **kwargs)