annotate contests/models.py @ 1165:3d17714c9a26

More forum thread tweaking WIP.
author Brian Neal <bgneal@gmail.com>
date Tue, 18 Apr 2017 20:13:59 -0500
parents eeaf387803c6
children
rev   line source
bgneal@540 1 """
bgneal@540 2 Models for the contest application.
bgneal@540 3
bgneal@540 4 """
bgneal@540 5 import random
bgneal@540 6 import datetime
bgneal@540 7
bgneal@1035 8 from django.contrib.auth.models import User
bgneal@1035 9 from django.core.urlresolvers import reverse
bgneal@540 10 from django.db import models
bgneal@540 11
bgneal@540 12
bgneal@540 13 class PublicContestManager(models.Manager):
bgneal@540 14 """
bgneal@540 15 The manager for all public contests.
bgneal@540 16
bgneal@540 17 """
bgneal@740 18 def get_queryset(self):
bgneal@740 19 return super(PublicContestManager, self).get_queryset().filter(is_public=True)
bgneal@540 20
bgneal@788 21 def get_current_contests(self):
bgneal@788 22 now = datetime.datetime.now()
bgneal@788 23 return self.filter(creation_date__lte=now, win_date__isnull=True)
bgneal@788 24
bgneal@540 25
bgneal@540 26 class Contest(models.Model):
bgneal@540 27 """
bgneal@540 28 A model to represent contests where users sign up to win something.
bgneal@540 29
bgneal@540 30 """
bgneal@540 31 title = models.CharField(max_length=64)
bgneal@540 32 slug = models.SlugField(max_length=64)
bgneal@540 33 description = models.TextField()
bgneal@929 34 is_public = models.BooleanField(default=False, db_index=True)
bgneal@540 35 creation_date = models.DateTimeField(blank=True)
bgneal@540 36 end_date = models.DateTimeField()
bgneal@540 37 contestants = models.ManyToManyField(User, related_name='contests',
bgneal@1028 38 blank=True)
bgneal@1028 39 winners = models.ManyToManyField(User, blank=True,
bgneal@540 40 related_name='winning_contests')
bgneal@540 41 win_date = models.DateTimeField(null=True, blank=True)
bgneal@540 42 meta_description = models.TextField()
bgneal@796 43 num_winners = models.IntegerField(default=1,
bgneal@796 44 verbose_name='Number of winners')
bgneal@540 45
bgneal@540 46 objects = models.Manager()
bgneal@540 47 public_objects = PublicContestManager()
bgneal@540 48
bgneal@540 49 class Meta:
bgneal@540 50 ordering = ['-creation_date']
bgneal@540 51
bgneal@540 52 def __unicode__(self):
bgneal@540 53 return self.title
bgneal@540 54
bgneal@540 55 def get_absolute_url(self):
bgneal@1035 56 return reverse('contests-contest', kwargs={'slug': self.slug})
bgneal@540 57
bgneal@540 58 def save(self, *args, **kwargs):
bgneal@540 59 if not self.pk and not self.creation_date:
bgneal@540 60 self.creation_date = datetime.datetime.now()
bgneal@540 61
bgneal@540 62 super(Contest, self).save(*args, **kwargs)
bgneal@540 63
bgneal@540 64 def is_active(self):
bgneal@540 65 """
bgneal@540 66 Returns True if the contest is still active.
bgneal@540 67
bgneal@540 68 """
bgneal@540 69 now = datetime.datetime.now()
bgneal@540 70 return self.creation_date <= now < self.end_date
bgneal@540 71
bgneal@540 72 def can_enter(self):
bgneal@540 73 """
bgneal@796 74 Returns True if the contest is still active and does not have any
bgneal@796 75 winners.
bgneal@540 76
bgneal@540 77 """
bgneal@796 78 return not self.win_date and self.is_active()
bgneal@540 79
bgneal@867 80 def can_comment_on(self):
bgneal@867 81 return self.is_active()
bgneal@867 82
bgneal@796 83 def pick_winners(self):
bgneal@540 84 """
bgneal@796 85 This function randomly picks winners from all the contestants.
bgneal@540 86
bgneal@540 87 """
bgneal@796 88 user_ids = list(self.contestants.values_list('id', flat=True))
bgneal@796 89
bgneal@796 90 winner_count = min(len(user_ids), self.num_winners)
bgneal@796 91 if winner_count == 0:
bgneal@796 92 return
bgneal@796 93
bgneal@796 94 winner_ids = []
bgneal@796 95 for n in xrange(winner_count):
bgneal@796 96 winner = random.choice(user_ids)
bgneal@796 97 winner_ids.append(winner)
bgneal@796 98 user_ids.remove(winner)
bgneal@796 99
bgneal@796 100 winners = list(User.objects.filter(pk__in=winner_ids))
bgneal@796 101 self.winners.add(*winners)
bgneal@540 102 self.win_date = datetime.datetime.now()
bgneal@540 103
bgneal@540 104 def ogp_tags(self):
bgneal@540 105 """
bgneal@540 106 Returns a dict of Open Graph Protocol meta tags.
bgneal@540 107
bgneal@540 108 """
bgneal@540 109 return {
bgneal@540 110 'og:title': self.title,
bgneal@567 111 'og:type': 'article',
bgneal@540 112 'og:url': self.get_absolute_url(),
bgneal@540 113 'og:description': self.meta_description,
bgneal@540 114 }