start static pages

This commit is contained in:
bkfox 2020-05-25 16:53:18 +02:00
parent c457ce873c
commit a59c4a3d5c
9 changed files with 117 additions and 37 deletions

View File

@ -1,6 +1,7 @@
from .article import ArticleAdmin
from .episode import DiffusionAdmin, EpisodeAdmin
from .log import LogAdmin
from .page import PageAdmin, StaticPageAdmin
from .program import ProgramAdmin, ScheduleAdmin, StreamAdmin
from .sound import SoundAdmin, TrackAdmin
from .station import StationAdmin

View File

@ -11,8 +11,7 @@ __all__ = ['ArticleAdmin']
@admin.register(Article)
class ArticleAdmin(PageAdmin):
list_filter = PageAdmin.list_filter
search_fields = PageAdmin.search_fields + ['parent__title']
search_fields = PageAdmin.search_fields + ('parent__title',)
# TODO: readonly field

View File

@ -56,7 +56,7 @@ class EpisodeAdmin(PageAdmin):
form = EpisodeAdminForm
list_display = PageAdmin.list_display
list_filter = PageAdmin.list_filter
search_fields = PageAdmin.search_fields + ['parent__title']
search_fields = PageAdmin.search_fields + ('parent__title',)
# readonly_fields = ('parent',)
inlines = [TracksInline, SoundInline, DiffusionInline]

View File

@ -1,4 +1,4 @@
import urllib
from copy import deepcopy
from django.contrib import admin
from django.http import QueryDict
@ -7,7 +7,7 @@ from django.utils.translation import gettext_lazy as _
from adminsortable2.admin import SortableInlineAdminMixin
from ..models import Category, NavItem, Page
from ..models import Category, NavItem, Page, StaticPage
__all__ = ['CategoryAdmin', 'PageAdmin', 'NavItemInline']
@ -22,25 +22,24 @@ class CategoryAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
# limit category choice
class PageAdmin(admin.ModelAdmin):
list_display = ('cover_thumb', 'title', 'status', 'category', 'parent')
class BasePageAdmin(admin.ModelAdmin):
list_display = ('cover_thumb', 'title', 'status', 'parent')
list_display_links = ('cover_thumb', 'title')
list_editable = ('status', 'category')
list_filter = ('status', 'category')
list_editable = ('status',)
list_filter = ('status',)
prepopulated_fields = {"slug": ("title",)}
# prepopulate fields using changelist's filters
prepopulated_filters = ('parent',)
search_fields = ['title', 'category__title']
search_fields = ('title',)
fieldsets = [
('', {
'fields': ['title', 'slug', 'category', 'cover', 'content'],
'fields': ['title', 'slug', 'cover', 'content'],
}),
(_('Publication Settings'), {
'fields': ['featured', 'allow_comments', 'status', 'parent'],
'classes': ('collapse',),
'fields': ['status', 'parent'],
# 'classes': ('collapse',),
}),
]
@ -59,10 +58,16 @@ class PageAdmin(admin.ModelAdmin):
def get_common_context(self, query, extra_context=None):
extra_context = extra_context or {}
parent = query.get('parent', None)
if parent is not None:
extra_context['parent'] = Page.objects.get_subclass(id=parent)
extra_context['parent'] = None if parent is None else \
Page.objects.get_subclass(id=parent)
return extra_context
def render_change_form(self, request, context, *args, **kwargs):
if context['original'] and not 'parent' in context:
context['parent'] = context['original'].parent
return super().render_change_form(request, context, *args, **kwargs)
def add_view(self, request, form_url='', extra_context=None):
filters = QueryDict(request.GET.get('_changelist_filters', ''))
extra_context = self.get_common_context(filters, extra_context)
@ -73,6 +78,27 @@ class PageAdmin(admin.ModelAdmin):
return super().changelist_view(request, extra_context)
class PageAdmin(BasePageAdmin):
list_display = BasePageAdmin.list_display + ('category',)
list_editable = BasePageAdmin.list_editable + ('category',)
list_filter = BasePageAdmin.list_editable + ('category',)
search_fields = ('category__title',)
fieldsets = deepcopy(BasePageAdmin.fieldsets)
fieldsets[0][1]['fields'].insert(fieldsets[0][1]['fields'].index('slug') + 1, 'category')
fieldsets[1][1]['fields'] += ('featured', 'allow_comments')
@admin.register(StaticPage)
class StaticPageAdmin(BasePageAdmin):
list_display = BasePageAdmin.list_display + ('view','menu_title')
list_editable = BasePageAdmin.list_editable + ('menu_title',)
fieldsets = deepcopy(BasePageAdmin.fieldsets)
fieldsets[0][1]['fields'].insert(fieldsets[0][1]['fields'].index('slug') + 1, 'menu_title')
fieldsets[1][1]['fields'] += ('view',)
class NavItemInline(SortableInlineAdminMixin, admin.TabularInline):
model = NavItem

View File

@ -1,5 +1,5 @@
from .article import Article
from .page import Category, Page, Comment, NavItem
from .page import Category, Page, StaticPage, Comment, NavItem
from .program import Program, Stream, Schedule
from .episode import Episode, Diffusion
from .log import Log

View File

@ -29,7 +29,7 @@ class LogQuerySet(models.QuerySet):
start = tz.datetime.combine(date, datetime.time())
end = tz.datetime.combine(date, datetime.time(23, 59, 59, 999))
return self.filter(date__range = (start, end))
# this filter does not work with sql
# this filter does not work with mysql
# return self.filter(date__date=date)
def after(self, date):

View File

@ -54,7 +54,7 @@ class PageQuerySet(InheritanceQuerySet):
self.filter(parent__id=id)
class Page(models.Model):
class BasePage(models.Model):
""" Base class for publishable content """
STATUS_DRAFT = 0x00
STATUS_PUBLISHED = 0x10
@ -72,30 +72,22 @@ class Page(models.Model):
status = models.PositiveSmallIntegerField(
_('status'), default=STATUS_DRAFT, choices=STATUS_CHOICES,
)
category = models.ForeignKey(
Category, models.SET_NULL,
verbose_name=_('category'), blank=True, null=True, db_index=True
)
cover = FilerImageField(
on_delete=models.SET_NULL,
verbose_name=_('Cover'), null=True, blank=True,
verbose_name=_('cover'), null=True, blank=True,
)
content = RichTextField(
_('content'), blank=True, null=True,
)
pub_date = models.DateTimeField(blank=True, null=True)
featured = models.BooleanField(
_('featured'), default=False,
)
allow_comments = models.BooleanField(
_('allow comments'), default=True,
)
objects = PageQuerySet.as_manager()
detail_url_name = None
item_template_name = 'aircox/widgets/page_item.html'
class Meta:
abstract = True
def __str__(self):
return '{}'.format(self.title or self.pk)
@ -106,10 +98,6 @@ class Page(models.Model):
count = Page.objects.filter(slug__startswith=self.slug).count()
if count:
self.slug += '-' + str(count)
if self.is_published and self.pub_date is None:
self.pub_date = tz.now()
elif not self.is_published:
self.pub_date = None
if not self.cover and self.parent:
self.cover = self.parent.cover
@ -150,9 +138,71 @@ class Page(models.Model):
return cls(**cls.get_init_kwargs_from(page, **kwargs))
class Page(BasePage):
""" Base Page model used for articles and other dated content. """
category = models.ForeignKey(
Category, models.SET_NULL,
verbose_name=_('category'), blank=True, null=True, db_index=True
)
pub_date = models.DateTimeField(blank=True, null=True)
featured = models.BooleanField(
_('featured'), default=False,
)
allow_comments = models.BooleanField(
_('allow comments'), default=True,
)
def save(self, *args, **kwargs):
if self.is_published and self.pub_date is None:
self.pub_date = tz.now()
elif not self.is_published:
self.pub_date = None
super().save(*args, **kwargs)
class StaticPage(Page):
""" Static page that eventually can be attached to a specific view. """
VIEW_HOME = 0x00
VIEW_SCHEDULE = 0x01
VIEW_LOG = 0x02
VIEW_PROGRAMS = 0x03
VIEW_EPISODES = 0x04
VIEW_ARTICLES = 0x05
VIEW_CHOICES = (
(VIEW_HOME, _('Home Page')),
(VIEW_SCHEDULE, _('Schedule Page')),
(VIEW_LOG, _('Log Page')),
(VIEW_PROGRAMS, _('Programs list')),
(VIEW_EPISODES, _('Episodes list')),
(VIEW_ARTICLES, _('Articles list')),
)
view = models.SmallIntegerField(
_('attach to'), choices=VIEW_CHOICES, blank=True, null=True,
help_text=_('display this page content to related element'),
)
menu_title = models.CharField(_('menu title'), max_length=64, blank=True, null=True)
is_active = False
def render_menu_item(self, request, css_class='', active_class=''):
if active_class and request.path.startswith(self.url):
css_class += ' ' + active_class
if not self.url:
return self.text
elif not css_class:
return format_html('<a href="{}">{}</a>', self.url, self.text)
else:
return format_html('<a href="{}" class="{}">{}</a>', self.url,
css_class, self.text)
class Comment(models.Model):
page = models.ForeignKey(
Page, models.CASCADE, verbose_name=_('related page'),
# TODO: allow_comment filter
)
nickname = models.CharField(_('nickname'), max_length=32)
email = models.EmailField(_('email'), max_length=32)

View File

@ -8,11 +8,9 @@
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; {% if has_view_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
{% with parent=parent|default:original.parent %}
{% if parent %}
&rsaquo; <a href="{% url opts|admin_urlname:"changelist" %}?parent={{parent.id}}">{{ parent.title }}</a>
{% endif %}
{% endwith %}
&rsaquo; {% if add %}{% blocktrans with name=opts.verbose_name %}Add {{ name }}{% endblocktrans %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>

View File

@ -60,6 +60,12 @@ urls = [
path(_('publications/'),
views.PageListView.as_view(model=models.Page), name='page-list'),
path(_('pages/'),
views.PageListView.as_view(model=models.StaticPage), name='static-page-list'),
path(_('pages/<slug:slug>/'),
views.PageDetailView.as_view(), name='page-detail'),
path(_('programs/'), views.ProgramListView.as_view(model=models.Program),
name='program-list'),
path(_('programs/<slug:slug>/'),