Source

django-diario / diario / models.py

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

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

from os import path

from django.conf import settings
from django.db import models
from django.utils.text import slugify
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
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
        )

    def highlighted(self):
        return self.visible().filter(highlight=True)


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()

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


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

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

    def __unicode__(self):
        return self.name

    def clean(self):
        if not self.slug:
            self.slug = slugify(self.name)

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


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,
        max_length=100
    )
    highlight = models.BooleanField(_('highlight'), default=False)
    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(
        settings.AUTH_USER_MODEL,
        editable=False,
        verbose_name=_('user'),
        on_delete=models.SET_NULL,
        null=True,
    )
    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,
        related_name='entries',
    )
    tags = TaggableManager(_('tags'), blank=True)

    objects = EntryManager()

    class Meta:
        get_latest_by = 'time_created'
        ordering = ('-time_created',)
        verbose_name = _('entry')
        verbose_name_plural = _('entries')
        permissions = (
            ("can_change_other_user_entry", "Can change other user entry"),
            ("can_delete_other_user_entry", "Can delete other user entry"),
        )

    def __unicode__(self):
        return self.title

    def clean(self):
        # Set time_published if entry is visible
        if self.is_visible():
            if not self.time_published:
                self.time_published = now()
        else:
            self.time_published = None
        # Set slug in case of not specified
        if not self.slug:
            self.slug = slugify(self.name)

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

    @models.permalink
    def get_preview_url(self):
        return ('diario:entry-preview', None, {'pk': self.pk})

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

    def is_hidden(self):
        return not self.status in self.VISIBLE_STATUS
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.