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
|
bgneal@1035
|
8 from django.core.urlresolvers import reverse
|
gremmie@1
|
9 from django.db import models
|
gremmie@1
|
10 from django.db.models import Q
|
gremmie@1
|
11
|
gremmie@1
|
12
|
gremmie@1
|
13 class PollManager(models.Manager):
|
bgneal@439
|
14 """Manager for the Poll model"""
|
gremmie@1
|
15
|
bgneal@439
|
16 def get_current_polls(self):
|
bgneal@439
|
17 now = datetime.datetime.now()
|
bgneal@439
|
18 return self.filter(
|
bgneal@439
|
19 Q(is_enabled=True),
|
bgneal@439
|
20 Q(start_date__lte=now),
|
bgneal@439
|
21 Q(end_date__isnull=True) | Q(end_date__gte=now))
|
gremmie@1
|
22
|
bgneal@439
|
23 def get_old_polls(self):
|
bgneal@439
|
24 now = datetime.datetime.now()
|
bgneal@439
|
25 return self.filter(
|
bgneal@439
|
26 is_enabled=True,
|
bgneal@439
|
27 end_date__isnull=False,
|
bgneal@439
|
28 end_date__lt=now)
|
gremmie@1
|
29
|
gremmie@1
|
30
|
gremmie@1
|
31 class Poll(models.Model):
|
bgneal@439
|
32 """Model to represent polls"""
|
bgneal@439
|
33 start_date = models.DateTimeField(db_index=True,
|
bgneal@439
|
34 help_text='Date/time the poll will be eligible for voting.',)
|
bgneal@439
|
35 end_date = models.DateTimeField(blank=True, null=True, db_index=True,
|
bgneal@439
|
36 help_text='Date/time the poll will be ineligible for voting. '
|
bgneal@439
|
37 'Leave blank for an open ended poll.')
|
bgneal@439
|
38 is_enabled = models.BooleanField(default=True, db_index=True,
|
bgneal@439
|
39 help_text='Check to allow the poll to be viewed on the site.')
|
bgneal@439
|
40 question = models.CharField(max_length=200)
|
gremmie@1
|
41
|
bgneal@439
|
42 objects = PollManager()
|
gremmie@1
|
43
|
bgneal@439
|
44 def __unicode__(self):
|
bgneal@439
|
45 return self.question
|
gremmie@1
|
46
|
bgneal@439
|
47 class Meta:
|
bgneal@439
|
48 ordering = ('-start_date', )
|
bgneal@439
|
49 get_latest_by = 'start_date'
|
gremmie@1
|
50
|
bgneal@439
|
51 def get_absolute_url(self):
|
bgneal@1035
|
52 return reverse('polls-detail', kwargs={'poll_id': str(self.pk)})
|
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
|