work on pages, filters, lists

This commit is contained in:
bkfox
2019-09-09 02:47:57 +02:00
parent c68e21ee57
commit 215a6ac331
45 changed files with 424 additions and 275 deletions

View File

@ -5,5 +5,5 @@ from .base import BaseView
from .episode import EpisodeDetailView, EpisodeListView, DiffusionListView
from .log import LogListView
from .page import PageDetailView, PageListView
from .program import ProgramDetailView
from .program import ProgramDetailView, ProgramPageListView

View File

@ -49,6 +49,9 @@ class AdminSite(admin.AdminSite):
path('tools/statistics/',
self.admin_view(StatisticsView.as_view()),
name='tools-stats'),
path('tools/statistics/<date:date>/',
self.admin_view(StatisticsView.as_view()),
name='tools-stats'),
]
return urls

View File

@ -7,10 +7,10 @@ __all__ = ['ArticleDetailView', 'ArticleListView']
class ArticleDetailView(PageDetailView):
show_side_nav = True
has_sidebar = True
model = Article
def get_side_queryset(self):
def get_sidebar_queryset(self):
qs = Article.objects.select_related('cover') \
.filter(is_static=False) \
.order_by('-date')
@ -27,9 +27,7 @@ class ArticleListView(ParentMixin, PageListView):
template_name = 'aircox/article_list.html'
show_headline = True
is_static = False
parent_model = Program
fk_parent = 'program'
def get_queryset(self):
return super().get_queryset().filter(is_static=self.is_static)

View File

@ -3,6 +3,7 @@ from django.http import Http404
from django.views.generic import DetailView, ListView
from django.views.generic.base import TemplateResponseMixin, ContextMixin
from ..models import Page
from ..utils import Redirect
@ -15,8 +16,10 @@ class BaseView(TemplateResponseMixin, ContextMixin):
cover = None
""" Page cover """
show_side_nav = False
has_sidebar = True
""" Show side navigation """
has_filters = False
""" Show filters nav """
list_count = 5
""" Item count for small lists displayed on page. """
@ -24,27 +27,29 @@ class BaseView(TemplateResponseMixin, ContextMixin):
def station(self):
return self.request.station
def get_queryset(self):
return super().get_queryset().station(self.station)
# def get_queryset(self):
# return super().get_queryset().station(self.station)
def get_side_queryset(self):
def get_sidebar_queryset(self):
""" Return a queryset of items to render on the side nav. """
return None
return Page.objects.select_subclasses().published() \
.order_by('-pub_date')
def get_context_data(self, side_items=None, **kwargs):
def get_context_data(self, sidebar_items=None, **kwargs):
kwargs.setdefault('station', self.station)
kwargs.setdefault('cover', self.cover)
kwargs.setdefault('has_filters', self.has_filters)
show_side_nav = kwargs.setdefault('show_side_nav', self.show_side_nav)
if show_side_nav and side_items is None:
side_items = self.get_side_queryset()
side_items = None if side_items is None else \
side_items[:self.list_count]
has_sidebar = kwargs.setdefault('has_sidebar', self.has_sidebar)
if has_sidebar and sidebar_items is None:
sidebar_items = self.get_sidebar_queryset()
sidebar_items = None if sidebar_items is None else \
sidebar_items[:self.list_count]
if not 'audio_streams' in kwargs:
streams = self.station.audio_streams
streams = streams and streams.split('\n')
kwargs['audio_streams'] = streams
return super().get_context_data(side_items=side_items, **kwargs)
return super().get_context_data(sidebar_items=sidebar_items, **kwargs)

View File

@ -35,18 +35,14 @@ class EpisodeListView(ParentMixin, PageListView):
model = Episode
item_template_name = 'aircox/episode_item.html'
show_headline = True
parent_model = Program
fk_parent = 'program'
class DiffusionListView(GetDateMixin, BaseView, ListView):
""" View for timetables """
model = Diffusion
date = None
start = None
end = None
has_filters = True
redirect_date_url = 'diffusion-list'
def get_date(self):
date = super().get_date()
@ -56,19 +52,7 @@ class DiffusionListView(GetDateMixin, BaseView, ListView):
return super().get_queryset().today(self.date).order_by('start')
def get_context_data(self, **kwargs):
today = datetime.date.today()
start = self.date - datetime.timedelta(days=self.date.weekday())
dates = [
(today, None),
(today - datetime.timedelta(days=1), None),
(today + datetime.timedelta(days=1), None),
(today - datetime.timedelta(days=7), _('next week')),
(today + datetime.timedelta(days=7), _('last week')),
(None, None)
] + [
(date, date.strftime('%A %d'))
for date in (start + datetime.timedelta(days=i)
for i in range(0, 7)) if date != today
]
dates = [start + datetime.timedelta(days=i) for i in range(0, 7)]
return super().get_context_data(date=self.date, dates=dates, **kwargs)

View File

@ -48,6 +48,9 @@ class LogListView(BaseView, LogListMixin, ListView):
Return list of logs for the provided date (from `kwargs` or
`request.GET`, defaults to today).
"""
redirect_date_url = 'log-list'
has_filters = True
def get_date(self):
date, today = super().get_date(), datetime.date.today()
return today if date is None else min(date, today)
@ -56,8 +59,7 @@ class LogListView(BaseView, LogListMixin, ListView):
today = datetime.date.today()
kwargs.update({
'date': self.date,
'dates': ((today - datetime.timedelta(days=i), None)
for i in range(0, 7)),
'dates': (today - datetime.timedelta(days=i) for i in range(0, 7)),
'object_list': self.get_object_list(self.object_list),
})
return super().get_context_data(**kwargs)

View File

@ -1,4 +1,6 @@
from django.shortcuts import get_object_or_404
import dateutil
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from ..utils import str_to_date
@ -12,13 +14,18 @@ class GetDateMixin:
`kwargs['date']`
"""
date = None
redirect_date_url = None
def get_date(self):
if 'date' in self.request.GET:
return str_to_date(self.request.GET['date'], '-')
return self.kwargs['date'] if 'date' in self.kwargs else None
date = self.request.GET.get('date')
return str_to_date(date, '-') if date is not None else \
self.kwargs['date'] if 'date' in self.kwargs else None
def get(self, *args, **kwargs):
if self.redirect_date_url and self.request.GET.get('date'):
return redirect(self.redirect_date_url,
date=self.request.GET['date'].replace('-', '/'))
self.date = self.get_date()
return super().get(*args, **kwargs)
@ -35,8 +42,6 @@ class ParentMixin:
""" Url lookup argument """
parent_field = 'slug'
""" Parent field for url lookup """
fk_parent = 'page'
""" Page foreign key to the parent """
parent = None
""" Parent page object """
@ -54,8 +59,7 @@ class ParentMixin:
def get_queryset(self):
if self.parent is not None:
lookup = {self.fk_parent: self.parent}
return super().get_queryset().filter(**lookup)
return super().get_queryset().filter(parent=self.parent)
return super().get_queryset()
def get_context_data(self, **kwargs):

View File

@ -1,6 +1,5 @@
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DetailView, ListView
@ -19,9 +18,11 @@ __all__ = ['PageDetailView', 'PageListView']
class PageListView(BaseView, ListView):
template_name = 'aircox/page_list.html'
item_template_name = 'aircox/page_item.html'
has_sidebar = True
has_filters = True
paginate_by = 20
show_headline = True
show_side_nav = True
categories = None
def get(self, *args, **kwargs):
@ -36,7 +37,7 @@ class PageListView(BaseView, ListView):
# (by id)
if self.categories:
qs = qs.filter(category__slug__in=self.categories)
return qs.order_by('-date')
return qs.order_by('-pub_date')
def get_categories_queryset(self):
# TODO: use generic reverse field lookup
@ -56,6 +57,7 @@ class PageListView(BaseView, ListView):
class PageDetailView(BaseView, DetailView):
""" Base view class for pages. """
context_object_name = 'page'
has_filters = False
def get_queryset(self):
return super().get_queryset().select_related('cover', 'category')

View File

@ -1,11 +1,13 @@
from django.db.models import Q
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404
from aircox.models import Episode, Program
from ..models import Episode, Program, Page
from .mixins import ParentMixin
from .page import PageDetailView, PageListView
__all__ = ['ProgramPageDetailView', 'ProgramDetailView']
__all__ = ['ProgramPageDetailView', 'ProgramDetailView', 'ProgramPageListView']
class ProgramPageDetailView(PageDetailView):
@ -13,24 +15,25 @@ class ProgramPageDetailView(PageDetailView):
Base view class for a page that is displayed as a program's child page.
"""
program = None
show_side_nav = True
has_sidebar = True
list_count = 5
def get_side_queryset(self):
return self.program.episode_set.published().order_by('-date')
def get_sidebar_queryset(self):
return super().get_sidebar_queryset().filter(parent=self.object)
class ProgramPageListView(ParentMixin, PageListView):
model = Page
parent_model = Program
queryset = Page.objects.select_subclasses()
class ProgramDetailView(ProgramPageDetailView):
model = Program
def get_articles_queryset(self):
return self.program.article_set.published().order_by('-date')
def get_context_data(self, **kwargs):
self.program = kwargs.setdefault('program', self.object)
if 'articles' not in kwargs:
kwargs['articles'] = \
self.get_articles_queryset()[:self.list_count]
return super().get_context_data(**kwargs)