annotate news/models.py @ 697:67f8d49a9377

Cleaned up the code a bit. Separated the S3 stuff out into its own class. This class maybe should be in core. Still want to do some kind of context manager around the temporary file we are creating to ensure it gets deleted.
author Brian Neal <bgneal@gmail.com>
date Sun, 08 Sep 2013 21:02:58 -0500
parents ee87ea74d46b
children 76525f5ac2b1
rev   line source
gremmie@1 1 """
gremmie@1 2 Models for the news application.
gremmie@1 3 """
gremmie@1 4
gremmie@1 5 import datetime
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
gremmie@1 10
gremmie@1 11 class Category(models.Model):
bgneal@54 12 """News stories belong to categories"""
bgneal@240 13 title = models.CharField(max_length=64)
bgneal@240 14 slug = models.SlugField(max_length=64)
bgneal@54 15 icon = models.ImageField(upload_to='news/categories/', blank=True)
gremmie@1 16
bgneal@54 17 def __unicode__(self):
bgneal@54 18 return self.title
gremmie@1 19
bgneal@54 20 def num_stories(self):
bgneal@54 21 return News.objects.filter(category = self.pk).count()
gremmie@1 22
bgneal@54 23 class Meta:
bgneal@54 24 verbose_name_plural = 'Categories'
bgneal@54 25 ordering = ('title', )
gremmie@1 26
gremmie@1 27
bgneal@204 28 class StoryBase(models.Model):
bgneal@204 29 """Abstract model to collect common fields."""
bgneal@54 30 title = models.CharField(max_length=255)
bgneal@54 31 submitter = models.ForeignKey(User)
bgneal@54 32 category = models.ForeignKey(Category)
bgneal@54 33 short_text = models.TextField()
bgneal@54 34 long_text = models.TextField(blank=True)
bgneal@204 35 date_submitted = models.DateTimeField(db_index=True)
bgneal@54 36 allow_comments = models.BooleanField(default=True)
bgneal@54 37 tags = TagField()
bgneal@218 38 front_page_expiration = models.DateField(null=True, blank=True)
bgneal@277 39 update_date = models.DateTimeField(db_index=True, blank=True)
bgneal@462 40 priority = models.IntegerField(db_index=True, default=0, blank=True)
bgneal@486 41 meta_description = models.TextField(blank=True)
gremmie@1 42
bgneal@204 43 class Meta:
bgneal@204 44 abstract = True
bgneal@204 45
bgneal@204 46
bgneal@204 47 class PendingStory(StoryBase):
bgneal@204 48 """Stories submitted by users are held pending admin approval"""
bgneal@204 49
bgneal@182 50 def save(self, *args, **kwargs):
bgneal@204 51 if not self.pk:
bgneal@277 52 if not self.date_submitted:
bgneal@277 53 self.date_submitted = datetime.datetime.now()
bgneal@277 54 self.update_date = self.date_submitted
bgneal@277 55 else:
bgneal@277 56 self.update_date = datetime.datetime.now()
bgneal@204 57
bgneal@204 58 super(PendingStory, self).save(*args, **kwargs)
gremmie@1 59
bgneal@54 60 def __unicode__(self):
bgneal@54 61 return self.title
gremmie@1 62
bgneal@54 63 class Meta:
bgneal@54 64 ordering = ('-date_submitted', )
bgneal@54 65 verbose_name_plural = 'Pending Stories'
gremmie@1 66
gremmie@1 67
bgneal@204 68 class Story(StoryBase):
bgneal@54 69 """Model for news stories"""
gremmie@1 70
bgneal@54 71 @models.permalink
bgneal@54 72 def get_absolute_url(self):
bgneal@54 73 return ('news.views.story', [str(self.id)])
gremmie@1 74
bgneal@54 75 def __unicode__(self):
bgneal@54 76 return self.title
gremmie@1 77
bgneal@54 78 class Meta:
bgneal@204 79 ordering = ('-date_submitted', )
bgneal@226 80 verbose_name = 'news story'
bgneal@226 81 verbose_name_plural = 'news stories'
gremmie@1 82
bgneal@277 83 def save(self, *args, **kwargs):
bgneal@277 84 if not self.pk:
bgneal@277 85 self.date_submitted = datetime.datetime.now()
bgneal@277 86 self.update_date = self.date_submitted
bgneal@277 87 else:
bgneal@277 88 self.update_date = datetime.datetime.now()
bgneal@277 89
bgneal@277 90 super(Story, self).save(*args, **kwargs)
bgneal@277 91
bgneal@54 92 def can_comment_on(self):
bgneal@54 93 now = datetime.datetime.now()
bgneal@204 94 delta = now - self.date_submitted
bgneal@204 95 return self.allow_comments and delta.days < 30
bgneal@220 96
bgneal@220 97 def search_title(self):
bgneal@220 98 return self.title
bgneal@220 99
bgneal@220 100 def search_summary(self):
bgneal@220 101 return u"\n".join((self.short_text, self.long_text))
bgneal@484 102
bgneal@484 103 def ogp_tags(self):
bgneal@484 104 """
bgneal@484 105 Returns a dict of Open Graph Protocol meta tags.
bgneal@484 106
bgneal@484 107 """
bgneal@486 108 desc = self.meta_description.strip()
bgneal@486 109 if not desc:
bgneal@486 110 desc = 'News article submitted by %s on %s.' % (
bgneal@486 111 self.submitter.username,
bgneal@486 112 self.date_submitted.strftime('%B %d, %Y'))
bgneal@486 113
bgneal@484 114 return {
bgneal@484 115 'og:title': self.title,
bgneal@484 116 'og:type': 'article',
bgneal@484 117 'og:url': self.get_absolute_url(),
bgneal@484 118 'og:image': self.category.icon.url,
bgneal@486 119 'og:description': desc,
bgneal@484 120 }