Permalink
Fetching contributors…
Cannot retrieve contributors at this time
253 lines (202 sloc) 8.26 KB
from pkg_resources import parse_version
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
from django.utils import six
from wagtail.core.models import Page, PageBase
from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.snippets.models import register_snippet
from wagtail.search import index
from wagtail.core import __version__ as WAGTAIL_VERSION
from taggit.models import TaggedItemBase, Tag as TaggitTag
from modelcluster.fields import ParentalKey
from colorful.fields import RGBColorField
from .abstracts import EntryAbstract
from .utils import import_model, get_image_model_path
from .routes import BlogRoutes
from .managers import TagManager, CategoryManager, BlogManager
Entry = import_model(getattr(settings, 'PUPUT_ENTRY_MODEL', EntryAbstract))
class BlogPage(BlogRoutes, Page):
description = models.CharField(
verbose_name=_('Description'),
max_length=255,
blank=True,
help_text=_("The blog description that will appear under the title.")
)
header_image = models.ForeignKey(
get_image_model_path(),
verbose_name=_('Header image'),
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
main_color = RGBColorField(_('Blog Main Color'), default="#4D6AE0")
display_comments = models.BooleanField(default=False, verbose_name=_('Display comments'))
display_categories = models.BooleanField(default=True, verbose_name=_('Display categories'))
display_tags = models.BooleanField(default=True, verbose_name=_('Display tags'))
display_popular_entries = models.BooleanField(default=True, verbose_name=_('Display popular entries'))
display_last_entries = models.BooleanField(default=True, verbose_name=_('Display last entries'))
display_archive = models.BooleanField(default=True, verbose_name=_('Display archive'))
disqus_api_secret = models.TextField(blank=True)
disqus_shortname = models.CharField(max_length=128, blank=True)
num_entries_page = models.IntegerField(default=5, verbose_name=_('Entries per page'))
num_last_entries = models.IntegerField(default=3, verbose_name=_('Last entries limit'))
num_popular_entries = models.IntegerField(default=3, verbose_name=_('Popular entries limit'))
num_tags_entry_header = models.IntegerField(default=5, verbose_name=_('Tags limit entry header'))
short_feed_description = models.BooleanField(default=True, verbose_name=_('Use short description in feeds'))
extra = BlogManager()
content_panels = Page.content_panels + [
FieldPanel('description', classname="full"),
ImageChooserPanel('header_image'),
FieldPanel('main_color')
]
settings_panels = Page.settings_panels + [
MultiFieldPanel(
[
FieldPanel('display_categories'),
FieldPanel('display_tags'),
FieldPanel('display_popular_entries'),
FieldPanel('display_last_entries'),
FieldPanel('display_archive'),
],
heading=_("Widgets")
),
MultiFieldPanel(
[
FieldPanel('num_entries_page'),
FieldPanel('num_last_entries'),
FieldPanel('num_popular_entries'),
FieldPanel('num_tags_entry_header'),
],
heading=_("Parameters")
),
MultiFieldPanel(
[
FieldPanel('display_comments'),
FieldPanel('disqus_api_secret'),
FieldPanel('disqus_shortname'),
],
heading=_("Comments")
),
MultiFieldPanel(
[
FieldPanel('short_feed_description'),
],
heading=_("Feeds")
),
]
subpage_types = ['puput.EntryPage']
def get_entries(self):
return EntryPage.objects.descendant_of(self).live().order_by('-date').select_related('owner')
def get_context(self, request, *args, **kwargs):
context = super(BlogPage, self).get_context(request, *args, **kwargs)
context['entries'] = self.entries
context['blog_page'] = self
context['search_type'] = getattr(self, 'search_type', "")
context['search_term'] = getattr(self, 'search_term', "")
return context
@property
def last_url_part(self):
"""
Get the BlogPage url without the domain
"""
return self.get_url_parts()[-1]
class Meta:
verbose_name = _('Blog')
@register_snippet
class Category(models.Model):
name = models.CharField(max_length=80, unique=True, verbose_name=_('Category name'))
slug = models.SlugField(unique=True, max_length=80)
parent = models.ForeignKey(
'self',
blank=True,
null=True,
related_name="children",
verbose_name=_('Parent category'),
on_delete=models.SET_NULL
)
description = models.CharField(max_length=500, blank=True, verbose_name=_('Description'))
objects = CategoryManager()
def __str__(self):
return self.name
def clean(self):
if self.parent:
parent = self.parent
if self.parent == self:
raise ValidationError(_('Parent category cannot be self.'))
if parent.parent and parent.parent == self:
raise ValidationError(_('Cannot have circular Parents.'))
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
return super(Category, self).save(*args, **kwargs)
class Meta:
ordering = ['name']
verbose_name = _("Category")
verbose_name_plural = _("Categories")
class CategoryEntryPage(models.Model):
category = models.ForeignKey(Category, related_name="+", verbose_name=_('Category'), on_delete=models.CASCADE)
page = ParentalKey('EntryPage', related_name='entry_categories')
panels = [
FieldPanel('category')
]
def __str__(self):
return str(self.category)
class TagEntryPage(TaggedItemBase):
content_object = ParentalKey('EntryPage', related_name='entry_tags')
@register_snippet
class Tag(TaggitTag):
objects = TagManager()
class Meta:
proxy = True
class EntryPageRelated(models.Model):
entrypage_from = ParentalKey('EntryPage', verbose_name=_("Entry"), related_name='related_entrypage_from')
entrypage_to = ParentalKey('EntryPage', verbose_name=_("Entry"), related_name='related_entrypage_to')
def __str__(self):
return str(self.entrypage_to)
def _add_owner_panel():
"""
Since Wagtail 1.11 EntryPage owner is set as `editable` it can be added to EntryPage
`settings_panels` if Puput is using a version greater or equal than 1.11.
See:
https://github.com/wagtail/wagtail/pull/3581
"""
if parse_version(WAGTAIL_VERSION) >= parse_version('1.11'):
return [FieldPanel('owner')]
return []
class EntryPage(six.with_metaclass(PageBase, Entry, Page)):
# Search
search_fields = Page.search_fields + [
index.SearchField('body'),
index.SearchField('excerpt'),
index.FilterField('page_ptr_id')
]
# Panels
content_panels = getattr(Entry, 'content_panels', [])
promote_panels = Page.promote_panels + getattr(Entry, 'promote_panels', [])
settings_panels = Page.settings_panels + [
FieldPanel('date')
] + _add_owner_panel() + getattr(Entry, 'settings_panels', [])
# Parent and child settings
parent_page_types = ['puput.BlogPage']
subpage_types = []
@property
def blog_page(self):
return self.get_parent().specific
@property
def related(self):
return [related.entrypage_to for related in self.related_entrypage_from.all()]
@property
def has_related(self):
return self.related_entrypage_from.count() > 0
def get_context(self, request, *args, **kwargs):
context = super(EntryPage, self).get_context(request, *args, **kwargs)
context['blog_page'] = self.blog_page
return context
class Meta:
verbose_name = _('Entry')
verbose_name_plural = _('Entries')