django-diario / diario / models.py

# -*- coding: utf-8 -*-

"""Models definitions for Diário"""

from os import path

from django.contrib.auth.models import User
from django.db import models
from django.utils.text import Truncator
from django.utils.translation import ugettext_lazy as _
from django.utils.timezone import now
from taggit.managers import TaggableManager

from diario import app_settings


SLUG_HELP_TEXT = _(
    'Automatically built from the title. A slug is a short '
    'label generally used in URLs.'
)


def filefield_path(instance, filename):
    today = now()
    year, month = today.strftime('%Y'), today.strftime('%m')
    filename = '{}-{}'.format(instance.id, filename)
    classname = instance.__class__.__name__.lower()
    return path.join(classname, year, month, filename)


class EntryQuerySet(models.query.QuerySet):
    def visible(self):
        return self.order_by('-time_published').filter(
            status__in=app_settings.VISIBLE_STATUS
        )


class EntryManager(models.Manager):
    def get_query_set(self):
        return EntryQuerySet(self.model, using=self._db)

    def visible(self):
        return self.get_query_set().visible()


class Category(models.Model):
    name = models.CharField(_('name'), max_length=64)
    slug = models.SlugField(_('slug'), help_text=SLUG_HELP_TEXT)

    class Meta:
        ordering = ('name',)
        verbose_name = _('category')
        verbose_name_plural = _('categories')

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return ('diario:category', None, {
            'name': self.name
        })


class Entry(models.Model):
    STATUS_CHOICES = app_settings.STATUS_CHOICES
    VISIBLE_STATUS = app_settings.VISIBLE_STATUS

    status = models.CharField(
        _('status'),
        max_length=16,
        choices=app_settings.STATUS_CHOICES,
        default='draft',
    )
    title = models.CharField(_('title'), max_length=100)
    slug = models.SlugField(_('slug'), help_text=SLUG_HELP_TEXT)
    featured_image = models.ImageField(
        _('featured image'),
        upload_to=filefield_path,
        blank=True
    )
    body = models.TextField(_('body'), blank=True)
    allow_comments = models.BooleanField(
        _('allow comments'),
        default=app_settings.ALLOW_COMMENTS,
    )
    user = models.ForeignKey(User, editable=False, verbose_name=_('user'))
    time_created = models.DateTimeField(_('creation time'), auto_now_add=True)
    time_modified = models.DateTimeField(_('modification time'), auto_now=True)
    time_published = models.DateTimeField(
        _('publication time'),
        editable=False, null=True,
    )
    categories = models.ManyToManyField(
        'Category',
        verbose_name=_('categories'),
        blank=True
    )
    tags = TaggableManager(_('tags'), blank=True)

    objects = EntryManager()

    class Meta:
        get_latest_by = 'time_created'
        ordering = ('-time_created',)
        verbose_name = _('entry')
        verbose_name_plural = _('entries')

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        if self.is_visible():
            if not self.time_published:
                self.time_published = now()
        else:
            self.time_published = None
        super(Entry, self).save(*args, **kwargs)

    @models.permalink
    def get_absolute_url(self):
        return ('diario:entry-detail', None, {
            'id': self.pk,
            'slug': self.slug
        })

    def is_visible(self):
        return self.status in self.VISIBLE_STATUS

    def is_hidden(self):
        return not self.status in self.VISIBLE_STATUS

    @property
    def lead(self):
        return Truncator(self.body).words(
            app_settings.LEAD_SIZE,
            truncate=' ...'
        )
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.