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
|