navigation & breadcrumbs
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
from . import admin, errors
|
||||
from .article import ArticleDetailView, ArticleListView
|
||||
from .base import BaseAPIView, BaseView
|
||||
from .diffusion import DiffusionListView
|
||||
from .diffusion import DiffusionListView, TimeTableView
|
||||
from .episode import EpisodeDetailView, EpisodeListView, PodcastListView
|
||||
from .home import HomeView
|
||||
from .log import LogListAPIView, LogListView
|
||||
@ -26,6 +26,7 @@ __all__ = (
|
||||
"BaseAPIView",
|
||||
"BaseView",
|
||||
"DiffusionListView",
|
||||
"TimeTableView",
|
||||
"EpisodeDetailView",
|
||||
"EpisodeListView",
|
||||
"PodcastListView",
|
||||
@ -40,4 +41,15 @@ __all__ = (
|
||||
"ProgramListView",
|
||||
"ProgramPageDetailView",
|
||||
"ProgramPageListView",
|
||||
"attached",
|
||||
)
|
||||
|
||||
|
||||
attached = {}
|
||||
|
||||
for key in __all__:
|
||||
view = globals().get(key)
|
||||
if key == "attached":
|
||||
continue
|
||||
if attach := getattr(view, "attach_to_value", None):
|
||||
attached[attach] = view
|
||||
|
@ -16,4 +16,4 @@ class ArticleListView(PageListView):
|
||||
model = Article
|
||||
has_headline = True
|
||||
parent_model = Program
|
||||
attach_to_value = StaticPage.ATTACH_TO_ARTICLES
|
||||
attach_to_value = StaticPage.Target.ARTICLES
|
||||
|
@ -18,6 +18,26 @@ class BaseView(TemplateResponseMixin, ContextMixin):
|
||||
# def get_queryset(self):
|
||||
# return super().get_queryset().station(self.station)
|
||||
|
||||
def get_nav_menu(self):
|
||||
menu = []
|
||||
for item in self.station.navitem_set.all():
|
||||
try:
|
||||
if item.page:
|
||||
view = item.page.get_related_view()
|
||||
secondary = view and view.get_secondary_nav()
|
||||
else:
|
||||
secondary = None
|
||||
menu.append((item, secondary))
|
||||
except:
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
raise
|
||||
return menu
|
||||
|
||||
def get_secondary_nav(self):
|
||||
return None
|
||||
|
||||
def get_related_queryset(self):
|
||||
"""Return a queryset of related pages or None."""
|
||||
return None
|
||||
@ -46,6 +66,8 @@ class BaseView(TemplateResponseMixin, ContextMixin):
|
||||
kwargs["title"] = page.display_title
|
||||
kwargs["cover"] = page.cover and page.cover.url
|
||||
|
||||
if "nav_menu" not in kwargs:
|
||||
kwargs["nav_menu"] = self.get_nav_menu()
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def dispatch(self, *args, **kwargs):
|
||||
|
@ -1,29 +1,54 @@
|
||||
import datetime
|
||||
|
||||
from django.urls import reverse
|
||||
from django.views.generic import ListView
|
||||
|
||||
from aircox.models import Diffusion, StaticPage
|
||||
from aircox.models import Diffusion, Log, StaticPage
|
||||
from .base import BaseView
|
||||
from .mixins import AttachedToMixin, GetDateMixin
|
||||
|
||||
__all__ = ("DiffusionListView",)
|
||||
__all__ = ("DiffusionListView", "TimeTableView")
|
||||
|
||||
|
||||
class DiffusionListView(GetDateMixin, AttachedToMixin, BaseView, ListView):
|
||||
class BaseDiffusionListView(AttachedToMixin, BaseView, ListView):
|
||||
model = Diffusion
|
||||
queryset = Diffusion.objects.on_air().order_by("-start")
|
||||
|
||||
|
||||
class DiffusionListView(BaseDiffusionListView):
|
||||
"""View for timetables."""
|
||||
|
||||
model = Diffusion
|
||||
redirect_date_url = "diffusion-list"
|
||||
attach_to_value = StaticPage.ATTACH_TO_DIFFUSIONS
|
||||
|
||||
|
||||
class TimeTableView(GetDateMixin, BaseDiffusionListView):
|
||||
model = Diffusion
|
||||
redirect_date_url = "timetable-list"
|
||||
attach_to_value = StaticPage.Target.TIMETABLE
|
||||
template_name = "aircox/timetable_list.html"
|
||||
|
||||
def get_date(self):
|
||||
date = super().get_date()
|
||||
return date if date is not None else datetime.date.today()
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().date(self.date).order_by("start")
|
||||
def get_logs(self, date):
|
||||
return Log.objects.on_air().date(self.date).filter(track__isnull=False)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().date(self.date)
|
||||
|
||||
@classmethod
|
||||
def get_secondary_nav(cls):
|
||||
date = datetime.date.today()
|
||||
start = date - datetime.timedelta(days=date.weekday())
|
||||
dates = [start + datetime.timedelta(days=i) for i in range(0, 7)]
|
||||
return tuple((date.strftime("%A %d"), reverse("timetable-list", kwargs={"date": date})) for date in dates)
|
||||
|
||||
def get_context_data(self, object_list=None, **kwargs):
|
||||
start = self.date - datetime.timedelta(days=self.date.weekday())
|
||||
dates = [start + datetime.timedelta(days=i) for i in range(0, 7)]
|
||||
return super().get_context_data(date=self.date, dates=dates, **kwargs)
|
||||
|
||||
if object_list is None:
|
||||
logs = self.get_logs(self.date)
|
||||
object_list = Log.merge_diffusions(logs, self.object_list)
|
||||
return super().get_context_data(date=self.date, dates=dates, object_list=object_list, **kwargs)
|
||||
|
@ -33,9 +33,9 @@ class EpisodeListView(PageListView):
|
||||
model = Episode
|
||||
filterset_class = EpisodeFilters
|
||||
parent_model = Program
|
||||
attach_to_value = StaticPage.ATTACH_TO_EPISODES
|
||||
attach_to_value = StaticPage.Target.EPISODES
|
||||
|
||||
|
||||
class PodcastListView(EpisodeListView):
|
||||
attach_to_value = StaticPage.ATTACH_TO_PODCASTS
|
||||
attach_to_value = StaticPage.Target.PODCASTS
|
||||
queryset = Episode.objects.published().with_podcasts().order_by("-pub_date")
|
||||
|
@ -10,7 +10,7 @@ from .mixins import AttachedToMixin
|
||||
|
||||
class HomeView(AttachedToMixin, BaseView, ListView):
|
||||
template_name = "aircox/home.html"
|
||||
attach_to_value = StaticPage.ATTACH_TO_HOME
|
||||
attach_to_value = StaticPage.Target.HOME
|
||||
model = Diffusion
|
||||
queryset = Diffusion.objects.on_air().select_related("episode").order_by("-start")
|
||||
|
||||
|
@ -6,12 +6,12 @@ from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import ListView
|
||||
from rest_framework.generics import ListAPIView
|
||||
|
||||
from ..models import Diffusion, Log, StaticPage
|
||||
from ..models import Diffusion, Log
|
||||
from ..serializers import LogInfo, LogInfoSerializer
|
||||
from .base import BaseAPIView, BaseView
|
||||
from .mixins import AttachedToMixin, GetDateMixin
|
||||
|
||||
__all__ = ["LogListMixin", "LogListView"]
|
||||
__all__ = ("LogListMixin", "LogListView", "LogListAPIView")
|
||||
|
||||
|
||||
class LogListMixin(GetDateMixin):
|
||||
@ -62,7 +62,6 @@ class LogListView(AttachedToMixin, BaseView, LogListMixin, ListView):
|
||||
`request.GET`, defaults to today)."""
|
||||
|
||||
redirect_date_url = "log-list"
|
||||
attach_to_value = StaticPage.ATTACH_TO_LOGS
|
||||
|
||||
def get_date(self):
|
||||
date = super().get_date()
|
||||
|
@ -44,16 +44,16 @@ class ParentMixin:
|
||||
parent = None
|
||||
"""Parent page object."""
|
||||
|
||||
def get_parent(self, request, *args, **kwargs):
|
||||
def get_parent(self, request, **kwargs):
|
||||
if self.parent_model is None or self.parent_url_kwarg not in kwargs:
|
||||
return
|
||||
|
||||
lookup = {self.parent_field: kwargs[self.parent_url_kwarg]}
|
||||
return get_object_or_404(self.parent_model.objects.select_related("cover"), **lookup)
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.parent = self.get_parent(request, *args, **kwargs)
|
||||
return super().get(request, *args, **kwargs)
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.parent = self.get_parent(request, **kwargs)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_queryset(self):
|
||||
if self.parent is not None:
|
||||
@ -61,9 +61,10 @@ class ParentMixin:
|
||||
return super().get_queryset()
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
self.parent = kwargs.setdefault("parent", self.parent)
|
||||
if self.parent is not None:
|
||||
kwargs.setdefault("cover", self.parent.cover.url)
|
||||
parent = kwargs.setdefault("parent", self.parent)
|
||||
|
||||
if parent is not None:
|
||||
kwargs.setdefault("cover", parent.cover.url)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.urls import reverse
|
||||
from honeypot.decorators import check_honeypot
|
||||
|
||||
from ..filters import PageFilters
|
||||
from ..forms import CommentForm
|
||||
from ..models import Comment
|
||||
from ..models import Comment, Category
|
||||
from ..utils import Redirect
|
||||
from .base import BaseView
|
||||
from .mixins import AttachedToMixin, FiltersMixin, ParentMixin
|
||||
@ -18,7 +19,25 @@ __all__ = [
|
||||
]
|
||||
|
||||
|
||||
class BasePageListView(AttachedToMixin, ParentMixin, BaseView, ListView):
|
||||
class BasePageMixin:
|
||||
category = None
|
||||
|
||||
def get_category(self, page, **kwargs):
|
||||
if page:
|
||||
if getattr(page, "category_id", None):
|
||||
return page.category
|
||||
if page.parent_id:
|
||||
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"
|
||||
@ -26,11 +45,18 @@ class BasePageListView(AttachedToMixin, ParentMixin, BaseView, ListView):
|
||||
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().select_subclasses().published().select_related("cover")
|
||||
if self.category:
|
||||
query = query.filter(category=self.category)
|
||||
return query
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs.setdefault("has_headline", self.has_headline)
|
||||
@ -48,12 +74,15 @@ class BasePageListView(AttachedToMixin, ParentMixin, BaseView, ListView):
|
||||
return context
|
||||
|
||||
|
||||
class BasePageDetailView(BaseView, DetailView):
|
||||
class BasePageDetailView(BasePageMixin, BaseView, DetailView):
|
||||
"""Base view class for BasePage."""
|
||||
|
||||
template_name = "aircox/basepage_detail.html"
|
||||
context_object_name = "page"
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
return super().get(*args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
if self.object.cover:
|
||||
kwargs.setdefault("cover", self.object.cover.url)
|
||||
@ -81,6 +110,8 @@ class BasePageDetailView(BaseView, DetailView):
|
||||
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):
|
||||
@ -105,26 +136,22 @@ 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
|
||||
|
||||
@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):
|
||||
self.categories = {
|
||||
id: title
|
||||
for title, id in self.model.objects.published()
|
||||
.filter(category__isnull=False)
|
||||
.values_list("category__title", "category__id")
|
||||
.distinct()
|
||||
}
|
||||
cat_id = self.request.GET.get("category__id")
|
||||
if cat_id:
|
||||
cat_id = int(cat_id)
|
||||
kwargs["category_id"] = cat_id
|
||||
|
||||
context = super().get_context_data(**kwargs)
|
||||
if context.get("parent") and not cat_id:
|
||||
kwargs["category_id"] = context["parent"].category_id
|
||||
|
||||
return context
|
||||
kwargs["categories"] = self.categories
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class PageDetailView(BasePageDetailView):
|
||||
@ -152,7 +179,6 @@ class PageDetailView(BasePageDetailView):
|
||||
if related:
|
||||
related = related[: self.related_count]
|
||||
kwargs["related_objects"] = related
|
||||
kwargs["related_url"] = self.get_related_url()
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
@classmethod
|
||||
|
@ -52,7 +52,7 @@ class ProgramDetailView(BaseProgramMixin, PageDetailView):
|
||||
|
||||
class ProgramListView(PageListView):
|
||||
model = Program
|
||||
attach_to_value = StaticPage.ATTACH_TO_PROGRAMS
|
||||
attach_to_value = StaticPage.Target.PROGRAMS
|
||||
|
||||
|
||||
# FIXME: not used
|
||||
|
Reference in New Issue
Block a user