annotate news/models.py @ 997:19b86e684cc2

WIP on news v2.0. Initial model changes and submit news functions.
author Brian Neal <bgneal@gmail.com>
date Tue, 17 Nov 2015 21:01:20 -0600
parents 76525f5ac2b1
children e2c3d7ecfa30
rev   line source
gremmie@1 1 """
gremmie@1 2 Models for the news application.
gremmie@1 3 """
bgneal@997 4 import datetime
gremmie@1 5
gremmie@1 6 from django.db import models
bgneal@49 7 from django.contrib.auth.models import User
gremmie@1 8 from tagging.fields import TagField
gremmie@1 9
bgneal@997 10 from core.markup import site_markup
bgneal@997 11
bgneal@997 12
bgneal@997 13 # News App versions
bgneal@997 14 NEWS_VERSION = 2
bgneal@997 15
gremmie@1 16
gremmie@1 17 class Category(models.Model):
bgneal@54 18 """News stories belong to categories"""
bgneal@240 19 title = models.CharField(max_length=64)
bgneal@240 20 slug = models.SlugField(max_length=64)
bgneal@54 21 icon = models.ImageField(upload_to='news/categories/', blank=True)
gremmie@1 22
bgneal@54 23 def __unicode__(self):
bgneal@54 24 return self.title
gremmie@1 25
bgneal@54 26 def num_stories(self):
bgneal@987 27 return Story.objects.filter(category=self.pk).count()
gremmie@1 28
bgneal@54 29 class Meta:
bgneal@54 30 verbose_name_plural = 'Categories'
bgneal@54 31 ordering = ('title', )
gremmie@1 32
gremmie@1 33
bgneal@204 34 class StoryBase(models.Model):
bgneal@204 35 """Abstract model to collect common fields."""
bgneal@54 36 title = models.CharField(max_length=255)
bgneal@54 37 submitter = models.ForeignKey(User)
bgneal@54 38 category = models.ForeignKey(Category)
bgneal@54 39 short_text = models.TextField()
bgneal@54 40 long_text = models.TextField(blank=True)
bgneal@204 41 date_submitted = models.DateTimeField(db_index=True)
bgneal@54 42 allow_comments = models.BooleanField(default=True)
bgneal@54 43 tags = TagField()
bgneal@218 44 front_page_expiration = models.DateField(null=True, blank=True)
bgneal@277 45 update_date = models.DateTimeField(db_index=True, blank=True)
bgneal@462 46 priority = models.IntegerField(db_index=True, default=0, blank=True)
bgneal@486 47 meta_description = models.TextField(blank=True)
bgneal@997 48 short_markup = models.TextField(default='')
bgneal@997 49 long_markup = models.TextField(default='', blank=True)
bgneal@997 50 admin_content = models.TextField(default='', blank=True)
bgneal@997 51 version = models.SmallIntegerField(default=NEWS_VERSION)
gremmie@1 52
bgneal@204 53 class Meta:
bgneal@204 54 abstract = True
bgneal@204 55
bgneal@182 56 def save(self, *args, **kwargs):
bgneal@204 57 if not self.pk:
bgneal@997 58 self.date_submitted = datetime.datetime.now()
bgneal@277 59 self.update_date = self.date_submitted
bgneal@277 60 else:
bgneal@277 61 self.update_date = datetime.datetime.now()
bgneal@204 62
bgneal@997 63 self.short_text = kwargs.pop('short_text', None)
bgneal@997 64 if self.short_text is None and self.short_markup:
bgneal@997 65 self.short_text = site_markup(self.short_markup)
bgneal@997 66
bgneal@997 67 self.long_text = kwargs.pop('long_text', None)
bgneal@997 68 if self.long_text is None and self.long_markup:
bgneal@997 69 self.long_text = site_markup(self.long_markup)
bgneal@997 70
bgneal@997 71 super(StoryBase, self).save(*args, **kwargs)
bgneal@997 72
bgneal@997 73
bgneal@997 74 class PendingStory(StoryBase):
bgneal@997 75 """Stories submitted by users are held pending admin approval"""
gremmie@1 76
bgneal@54 77 def __unicode__(self):
bgneal@54 78 return self.title
gremmie@1 79
bgneal@54 80 class Meta:
bgneal@997 81 ordering = ['-date_submitted']
bgneal@54 82 verbose_name_plural = 'Pending Stories'
gremmie@1 83
gremmie@1 84
bgneal@204 85 class Story(StoryBase):
bgneal@54 86 """Model for news stories"""
gremmie@1 87
bgneal@54 88 @models.permalink
bgneal@54 89 def get_absolute_url(self):
bgneal@54 90 return ('news.views.story', [str(self.id)])
gremmie@1 91
bgneal@54 92 def __unicode__(self):
bgneal@54 93 return self.title
gremmie@1 94
bgneal@54 95 class Meta:
bgneal@997 96 ordering = ['-date_submitted']
bgneal@226 97 verbose_name = 'news story'
bgneal@226 98 verbose_name_plural = 'news stories'
gremmie@1 99
bgneal@54 100 def can_comment_on(self):
bgneal@54 101 now = datetime.datetime.now()
bgneal@204 102 delta = now - self.date_submitted
bgneal@204 103 return self.allow_comments and delta.days < 30
bgneal@220 104
bgneal@220 105 def search_title(self):
bgneal@220 106 return self.title
bgneal@220 107
bgneal@220 108 def search_summary(self):
bgneal@220 109 return u"\n".join((self.short_text, self.long_text))
bgneal@484 110
bgneal@484 111 def ogp_tags(self):
bgneal@484 112 """
bgneal@484 113 Returns a dict of Open Graph Protocol meta tags.
bgneal@484 114
bgneal@484 115 """
bgneal@486 116 desc = self.meta_description.strip()
bgneal@486 117 if not desc:
bgneal@486 118 desc = 'News article submitted by %s on %s.' % (
bgneal@486 119 self.submitter.username,
bgneal@486 120 self.date_submitted.strftime('%B %d, %Y'))
bgneal@486 121
bgneal@484 122 return {
bgneal@484 123 'og:title': self.title,
bgneal@484 124 'og:type': 'article',
bgneal@484 125 'og:url': self.get_absolute_url(),
bgneal@484 126 'og:image': self.category.icon.url,
bgneal@486 127 'og:description': desc,
bgneal@484 128 }