annotate polls/models.py @ 661:15dbe0ccda95

Prevent exceptions when viewing downloads in the admin when the file doesn't exist on the filesystem. This is usually seen in development but can also happen in production if the file is missing.
author Brian Neal <bgneal@gmail.com>
date Tue, 14 May 2013 21:02:47 -0500
parents ee87ea74d46b
children eeaf387803c6
rev   line source
bgneal@367 1 """
gremmie@1 2 Models for the Polls application.
gremmie@1 3
bgneal@367 4 """
gremmie@1 5 import datetime
bgneal@439 6
bgneal@439 7 from django.contrib.auth.models import User
gremmie@1 8 from django.db import models
gremmie@1 9 from django.db.models import Q
gremmie@1 10
gremmie@1 11
gremmie@1 12 class PollManager(models.Manager):
bgneal@439 13 """Manager for the Poll model"""
gremmie@1 14
bgneal@439 15 def get_current_polls(self):
bgneal@439 16 now = datetime.datetime.now()
bgneal@439 17 return self.filter(
bgneal@439 18 Q(is_enabled=True),
bgneal@439 19 Q(start_date__lte=now),
bgneal@439 20 Q(end_date__isnull=True) | Q(end_date__gte=now))
gremmie@1 21
bgneal@439 22 def get_old_polls(self):
bgneal@439 23 now = datetime.datetime.now()
bgneal@439 24 return self.filter(
bgneal@439 25 is_enabled=True,
bgneal@439 26 end_date__isnull=False,
bgneal@439 27 end_date__lt=now)
gremmie@1 28
gremmie@1 29
gremmie@1 30 class Poll(models.Model):
bgneal@439 31 """Model to represent polls"""
bgneal@439 32 start_date = models.DateTimeField(db_index=True,
bgneal@439 33 help_text='Date/time the poll will be eligible for voting.',)
bgneal@439 34 end_date = models.DateTimeField(blank=True, null=True, db_index=True,
bgneal@439 35 help_text='Date/time the poll will be ineligible for voting. '
bgneal@439 36 'Leave blank for an open ended poll.')
bgneal@439 37 is_enabled = models.BooleanField(default=True, db_index=True,
bgneal@439 38 help_text='Check to allow the poll to be viewed on the site.')
bgneal@439 39 question = models.CharField(max_length=200)
gremmie@1 40
bgneal@439 41 objects = PollManager()
gremmie@1 42
bgneal@439 43 def __unicode__(self):
bgneal@439 44 return self.question
gremmie@1 45
bgneal@439 46 class Meta:
bgneal@439 47 ordering = ('-start_date', )
bgneal@439 48 get_latest_by = 'start_date'
gremmie@1 49
bgneal@439 50 @models.permalink
bgneal@439 51 def get_absolute_url(self):
bgneal@439 52 return ('polls-detail', [], {'poll_id': str(self.id)})
gremmie@1 53
bgneal@439 54 def results(self):
bgneal@439 55 """
bgneal@439 56 Returns a tuple; element 0 is the total votes, element 1 is a list of
bgneal@439 57 {choice, votes, pct}
bgneal@439 58 """
bgneal@439 59 choices = []
bgneal@439 60 total_votes = 0
bgneal@439 61 for choice in self.choice_set.all():
bgneal@439 62 total_votes += choice.votes
bgneal@439 63 choices.append({'choice': choice.choice, 'votes': choice.votes, 'pct': 0.0})
gremmie@1 64
bgneal@439 65 if total_votes > 0:
bgneal@439 66 for choice in choices:
bgneal@439 67 choice['pct'] = float(choice['votes']) / total_votes * 100.0
gremmie@1 68
bgneal@439 69 return (total_votes, choices)
gremmie@1 70
bgneal@440 71 def _total_votes(self):
bgneal@439 72 """
bgneal@439 73 Returns the number of votes cast in this poll to date.
gremmie@1 74
bgneal@439 75 """
bgneal@440 76 if not hasattr(self, '_total_votes_cache'):
bgneal@440 77 self._total_votes_cache = sum(choice.votes for choice in
bgneal@440 78 self.choice_set.all())
bgneal@440 79 return self._total_votes_cache
bgneal@440 80 total_votes = property(_total_votes)
bgneal@439 81
bgneal@439 82 def is_open(self):
bgneal@439 83 now = datetime.datetime.now()
bgneal@439 84 return self.start_date <= now and (not self.end_date or now <= self.end_date)
bgneal@439 85
bgneal@439 86 def can_comment_on(self):
bgneal@439 87 return self.is_open()
gremmie@1 88
gremmie@1 89
gremmie@1 90 class Choice(models.Model):
bgneal@439 91 """Model for poll choices"""
bgneal@439 92 poll = models.ForeignKey(Poll)
bgneal@439 93 choice = models.CharField(max_length=200)
bgneal@439 94 votes = models.IntegerField(default=0)
bgneal@439 95 voters = models.ManyToManyField(User, blank=True)
gremmie@1 96
bgneal@439 97 def __unicode__(self):
bgneal@439 98 return self.choice