Mercurial > public > sg101
comparison gpp/polls/models.py @ 439:1f139de929c4
Fixing #216; added anti-ballot stuffing feature to the polls application.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 21 May 2011 19:55:48 +0000 |
parents | cb121a3abf46 |
children | ac9217eef610 |
comparison
equal
deleted
inserted
replaced
438:524fd1b3919a | 439:1f139de929c4 |
---|---|
1 """ | 1 """ |
2 Models for the Polls application. | 2 Models for the Polls application. |
3 | 3 |
4 """ | 4 """ |
5 import datetime | 5 import datetime |
6 | |
7 from django.contrib.auth.models import User | |
6 from django.db import models | 8 from django.db import models |
7 from django.db.models import Q | 9 from django.db.models import Q |
8 | 10 |
9 | 11 |
10 class PollManager(models.Manager): | 12 class PollManager(models.Manager): |
11 """Manager for the Poll model""" | 13 """Manager for the Poll model""" |
12 | 14 |
13 def get_current_polls(self): | 15 def get_current_polls(self): |
14 now = datetime.datetime.now() | 16 now = datetime.datetime.now() |
15 return self.filter( | 17 return self.filter( |
16 Q(is_enabled=True), | 18 Q(is_enabled=True), |
17 Q(start_date__lte=now), | 19 Q(start_date__lte=now), |
18 Q(end_date__isnull=True) | Q(end_date__gte=now)) | 20 Q(end_date__isnull=True) | Q(end_date__gte=now)) |
19 | 21 |
20 def get_old_polls(self): | 22 def get_old_polls(self): |
21 now = datetime.datetime.now() | 23 now = datetime.datetime.now() |
22 return self.filter( | 24 return self.filter( |
23 Q(is_enabled=True), | 25 is_enabled=True, |
24 Q(end_date__isnull=False), | 26 end_date__isnull=False, |
25 Q(end_date__lt=now)) | 27 end_date__lt=now) |
26 | 28 |
27 | 29 |
28 class Poll(models.Model): | 30 class Poll(models.Model): |
29 """Model to represent polls""" | 31 """Model to represent polls""" |
30 start_date = models.DateTimeField(db_index=True, | 32 start_date = models.DateTimeField(db_index=True, |
31 help_text='Date/time the poll will be eligible for voting.',) | 33 help_text='Date/time the poll will be eligible for voting.',) |
32 end_date = models.DateTimeField(blank=True, null=True, db_index=True, | 34 end_date = models.DateTimeField(blank=True, null=True, db_index=True, |
33 help_text='Date/time the poll will be ineligible for voting. ' | 35 help_text='Date/time the poll will be ineligible for voting. ' |
34 'Leave blank for an open ended poll.') | 36 'Leave blank for an open ended poll.') |
35 is_enabled = models.BooleanField(default=True, db_index=True, | 37 is_enabled = models.BooleanField(default=True, db_index=True, |
36 help_text='Check to allow the poll to be viewed on the site.') | 38 help_text='Check to allow the poll to be viewed on the site.') |
37 question = models.CharField(max_length=200) | 39 question = models.CharField(max_length=200) |
38 | 40 |
39 objects = PollManager() | 41 objects = PollManager() |
40 | 42 |
41 def __unicode__(self): | 43 def __unicode__(self): |
42 return self.question | 44 return self.question |
43 | 45 |
44 class Meta: | 46 class Meta: |
45 ordering = ('-start_date', ) | 47 ordering = ('-start_date', ) |
46 get_latest_by = 'start_date' | 48 get_latest_by = 'start_date' |
47 | 49 |
48 @models.permalink | 50 @models.permalink |
49 def get_absolute_url(self): | 51 def get_absolute_url(self): |
50 return ('polls.views.poll_detail', [str(self.id)]) | 52 return ('polls-detail', [], {'poll_id': str(self.id)}) |
51 | 53 |
52 def results(self): | 54 def results(self): |
53 """ | 55 """ |
54 Returns a tuple; element 0 is the total votes, element 1 is a list of | 56 Returns a tuple; element 0 is the total votes, element 1 is a list of |
55 {choice, votes, pct} | 57 {choice, votes, pct} |
56 """ | 58 """ |
57 choices = [] | 59 choices = [] |
58 total_votes = 0 | 60 total_votes = 0 |
59 for choice in self.choice_set.all(): | 61 for choice in self.choice_set.all(): |
60 total_votes += choice.votes | 62 total_votes += choice.votes |
61 choices.append({'choice': choice.choice, 'votes': choice.votes, 'pct': 0.0}) | 63 choices.append({'choice': choice.choice, 'votes': choice.votes, 'pct': 0.0}) |
62 | 64 |
63 if total_votes > 0: | 65 if total_votes > 0: |
64 for choice in choices: | 66 for choice in choices: |
65 choice['pct'] = float(choice['votes']) / total_votes * 100.0 | 67 choice['pct'] = float(choice['votes']) / total_votes * 100.0 |
66 | 68 |
67 return (total_votes, choices) | 69 return (total_votes, choices) |
68 | 70 |
69 def is_open(self): | 71 def total_votes(self): |
70 now = datetime.datetime.now() | 72 """ |
71 return self.start_date <= now and (not self.end_date or now <= self.end_date) | 73 Returns the number of votes cast in this poll to date. |
72 | 74 |
73 def can_comment_on(self): | 75 """ |
74 return self.is_open() | 76 return sum(choice.votes for choice in self.choice_set.all()) |
77 | |
78 def is_open(self): | |
79 now = datetime.datetime.now() | |
80 return self.start_date <= now and (not self.end_date or now <= self.end_date) | |
81 | |
82 def can_comment_on(self): | |
83 return self.is_open() | |
75 | 84 |
76 | 85 |
77 class Choice(models.Model): | 86 class Choice(models.Model): |
78 """Model for poll choices""" | 87 """Model for poll choices""" |
79 poll = models.ForeignKey(Poll) | 88 poll = models.ForeignKey(Poll) |
80 choice = models.CharField(max_length = 200) | 89 choice = models.CharField(max_length=200) |
81 votes = models.IntegerField(default = 0) | 90 votes = models.IntegerField(default=0) |
91 voters = models.ManyToManyField(User, blank=True) | |
82 | 92 |
83 def __unicode__(self): | 93 def __unicode__(self): |
84 return self.choice | 94 return self.choice |