annotate polls/models.py @ 945:7ab180ff6f7b

Merge upstream.
author Brian Neal <bgneal@gmail.com>
date Wed, 13 May 2015 20:29:23 -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