annotate polls/models.py @ 887:9a15f7c27526

Actually save model object upon change. This commit was tested on the comments model. Additional logging added. Added check for Markdown image references. Added TODOs after observing behavior on comments.
author Brian Neal <bgneal@gmail.com>
date Tue, 03 Feb 2015 21:09:44 -0600
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