Files
kasu/content/models.py
Christian Berg 86a0db050d Diverse Code Cleanups
*Code wurde PEP-8 gerecht formatiert
* Kleine Fehler die der PyCharm Inspector beanstandet wurden korrigiert
2014-11-26 16:04:52 +01:00

268 lines
9.1 KiB
Python

# -*- coding: utf-8 -*-
from os import path
from django.conf import settings
from django.utils.timezone import now
from django.core.urlresolvers import reverse
from django.core.cache import cache
from django.db import models
from django.template.defaultfilters import slugify
from django.utils.safestring import mark_safe
from django.utils.translation import get_language, ugettext as _
from imagekit.models import ImageSpecField
from imagekit.processors import SmartResize
from django.core.exceptions import ValidationError
from utils import STATUS_CHOICES, STATUS_WAITING, STATUS_PUBLISHED, \
cleaner
CONTENT_CHOICES = (
(0, u'Django View'),
(1, u'HTML'),
(2, u'PDF')
)
def get_upload_path(instance, filename):
"""
Generates the desired file path and filename for an uploaded Image.
With this function Django can save the uploaded images to subfolders that
also have a meaning for humans.
@param instance: an Django Object for which the Image has been uploaded.
@type instance: a instace of an models.Model sub-class.
@param filename: The filename of the uploaded image.
@type filename: String
"""
extension = filename[filename.rfind('.') + 1:]
if isinstance(instance, Category):
return "categories/%s.%s" % (instance.slug, extension)
class ImageModel(models.Model):
article = ImageSpecField(
source='image',
processors=[SmartResize(width=210, height=130)]
)
class Meta:
abstract = True
class ArticleManager(models.Manager):
def published(self):
return self.filter(status=STATUS_PUBLISHED, date_created__lte=now())
class Article(ImageModel):
headline_de = models.CharField(_('Headline'), max_length=255)
headline_en = models.CharField('Headline', max_length=255, blank=True)
content_de = models.TextField(_('Content'))
content_en = models.TextField('Content', blank=True)
category = models.ForeignKey('Category', verbose_name=_('Category'))
image = models.ImageField(_('Image'), upload_to='news/',
blank=True, null=True)
slug = models.SlugField(_('Slug'), unique_for_month='date_created')
author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('Author'))
status = models.SmallIntegerField(_('Status'), choices=STATUS_CHOICES,
default=STATUS_PUBLISHED)
date_created = models.DateField(_('Created'), blank=True)
date_modified = models.DateTimeField(_('Modified'), auto_now=True)
objects = ArticleManager()
class Meta(object):
verbose_name = _('Article')
verbose_name_plural = _('Articles')
ordering = ('-date_created',)
def clean(self):
if not self.date_created:
self.date_created = now()
if not self.slug:
self.slug = slugify(self.headline_de)[:50]
self.content_de = cleaner.clean_html(self.content_de)
self.content_en = cleaner.clean_html(self.content_en)
def __unicode__(self):
return self.headline
@property
def posting_image(self):
if self.image:
return self.article
else:
return self.category.article
def get_absolute_url(self):
kwargs = {
'year': self.date_created.strftime('%Y'),
'month': self.date_created.strftime('%m'),
'slug': self.slug,
}
return reverse('show-article', kwargs=kwargs)
@property
def headline(self):
headline = getattr(self, "headline_%s" % get_language())
if not headline:
return mark_safe(self.headline_de)
else:
return mark_safe(headline)
@property
def content(self):
content = getattr(self, "content_%s" % get_language(), self.content_de)
if not content:
return mark_safe(self.content_de)
else:
return mark_safe(content)
class Page(models.Model):
"""
Eine Seite auf der Homepage. Sie kann eine "statische" HTML Seite,
die URL einer dynamische Django View, oder ein PDF Dokument sein.
Jede Seite kann neben Deutsch auch auf Englisch angeboten werden.
Ist keine englische Übersetzung vorhanden, wird die deutsche Version
angeboten.
"""
menu_name_de = models.CharField(
'Menü Name',
max_length=255,
help_text=_('The short name for the menu-entry of this page')
)
menu_name_en = models.CharField(
'Menu Name',
max_length=255,
blank=True,
help_text=_('The short name for the menu-entry of this page')
)
title_de = models.CharField('Titel', max_length=255,
help_text=_('This title appears in the HTML header'))
title_en = models.CharField('Title', max_length=255, blank=True,
help_text=_('This title appears in the HTML header'))
slug = models.SlugField(_('slug'))
path = models.CharField(_('Path'), max_length=100, db_index=True,
editable=False, unique=True)
parent = models.ForeignKey('self', blank=True, null=True,
related_name='subpages', on_delete=models.SET_NULL)
position = models.PositiveSmallIntegerField(_('Position'),
blank=True, null=True)
status = models.SmallIntegerField(_('status'), choices=STATUS_CHOICES,
default=STATUS_WAITING)
content_type = models.IntegerField(choices=CONTENT_CHOICES)
content_de = models.TextField('Inhalt', blank=True)
content_en = models.TextField('Content', blank=True)
enable_comments = models.BooleanField(_('enable comments'), default=True)
template = models.CharField(_('Template'), max_length=100,
default="content/page.html")
pdf_de = models.FileField(upload_to='pdf/de/', blank=True, null=True)
pdf_en = models.FileField(upload_to='pdf/en/', blank=True, null=True)
def __unicode__(self):
return u'%s' % self.title
@property
def content(self):
cont = getattr(self, "content_%s" % get_language()) or self.content_de
return mark_safe(cont)
@property
def css_class(self):
return CONTENT_CHOICES[self.content_type][1].lower().replace(' ', '_')
@property
def menu_name(self):
return getattr(self,
"menu_name_%s" % get_language()) or self.menu_name_de
@property
def pdf_file(self):
return getattr(self, "pdf_%s" % get_language()) or self.pdf_de
@property
def title(self):
return getattr(self, "title_%s" % get_language()) or self.title_de
def clean(self):
if self.parent is None:
self.path = self.slug
else:
self.path = path.join(self.parent.path, self.slug)
if self.content_type is None:
if self.pdf_de:
self.content_type = 2
if self.content_de:
self.content_type = 1
else:
self.content_type = 0
if self.content_type == 1:
self.content_de = cleaner.clean_html(self.content_de)
self.content_en = cleaner.clean_html(self.content_en)
elif self.content_type == 2 and not self.pdf_de.name:
raise ValidationError(
_(u'Please upload a PDF-File to this PDF-Page.'))
def get_absolute_url(self):
aboslute_url = '/' + self.path
if self.content_type == 1:
aboslute_url += '.html'
elif self.content_type == 2:
aboslute_url += '.pdf'
else:
aboslute_url += '/'
return aboslute_url
class Meta(object):
ordering = ['parent__id', 'position']
unique_together = (('slug', 'parent'),)
verbose_name = _('Page')
verbose_name_plural = _('Pages')
class Category(ImageModel):
name_de = models.CharField(_('Name'), max_length=80)
name_en = models.CharField(_('Name'), max_length=80, blank=True)
description_de = models.TextField(_('Description'))
description_en = models.TextField(_('Description'), blank=True)
image = models.ImageField(_('Image'), upload_to='news/categories/',
blank=True, null=True)
slug = models.SlugField(_('Slug'), unique=True, db_index=True)
class Meta(object):
ordering = ('slug',)
verbose_name = _('Category')
verbose_name_plural = _('Categories')
@property
def name(self):
return getattr(self, "name_%s" % get_language(), self.name_de)
@property
def description(self):
return getattr(self, "description_%s" % get_language(),
self.description_de)
def get_absolute_url(self):
return reverse('article-archive', kwargs={'category': self.slug})
def __unicode__(self):
return self.name
def force_cache_update(sender, instance, **kwargs):
for page in instance.subpages.all():
page.clean()
page.save()
cache.delete('all_pages')
cache.delete('top_level_pages')
models.signals.post_delete.connect(force_cache_update, sender=Page)
models.signals.post_save.connect(force_cache_update, sender=Page)