from django.db import models # internal text/value object class SurveyQuestion(object): def __init__(self, value, text): self.value = value self.text = text class SurveyAnswerValues(object): def __init__(self, option, votes, votespercent): self.option = option self.votes = votes self.votespercent = votespercent class Survey(models.Model): question = models.CharField(max_length=500, null=False, blank=False) opt1 = models.CharField(max_length=500, null=False, blank=False) opt2 = models.CharField(max_length=500, null=False, blank=False) opt3 = models.CharField(max_length=500, null=False, blank=True) opt4 = models.CharField(max_length=500, null=False, blank=True) opt5 = models.CharField(max_length=500, null=False, blank=True) opt6 = models.CharField(max_length=500, null=False, blank=True) opt7 = models.CharField(max_length=500, null=False, blank=True) opt8 = models.CharField(max_length=500, null=False, blank=True) posted = models.DateTimeField(null=False, auto_now_add=True) current = models.BooleanField(null=False, default=False) purge_urls = ('/community/survey', '/community/$') def __str__(self): return self.question @property def questions(self): for i in range(1, 9): v = getattr(self, "opt%s" % i) if not v: break yield SurveyQuestion(i, v) @property def answers(self): if not hasattr(self, "_answers"): self._answers = SurveyAnswer.objects.get_or_create(survey=self)[0] return self._answers @property def completeanswers(self): for a in self._get_complete_answers(): yield SurveyAnswerValues(a[0], a[1], self.totalvotes > 0 and (100 * a[1] / self.totalvotes) or 0) @property def totalvotes(self): if not hasattr(self, "_totalvotes"): self._totalvotes = 0 for a in self._get_complete_answers(): self._totalvotes = self._totalvotes + a[1] return self._totalvotes def _get_complete_answers(self): for i in range(1, 9): q = getattr(self, "opt%s" % i) if not q: break n = getattr(self.answers, "tot%s" % i) yield (q, n) def save(self): # Make sure only one survey at a time can be the current one # (there may be some small race conditions here, but the likelihood # that two admins are editing the surveys at the same time...) if self.current: previous = Survey.objects.filter(current=True) for p in previous: if not p == self: p.current = False p.save() # primary key check avoids recursion # Now that we've made any previously current ones non-current, we are # free to save this one. super(Survey, self).save() class SurveyAnswer(models.Model): survey = models.OneToOneField(Survey, null=False, blank=False, primary_key=True, on_delete=models.CASCADE) tot1 = models.IntegerField(null=False, default=0) tot2 = models.IntegerField(null=False, default=0) tot3 = models.IntegerField(null=False, default=0) tot4 = models.IntegerField(null=False, default=0) tot5 = models.IntegerField(null=False, default=0) tot6 = models.IntegerField(null=False, default=0) tot7 = models.IntegerField(null=False, default=0) tot8 = models.IntegerField(null=False, default=0) purge_urls = ('/community/survey', ) class SurveyLock(models.Model): ipaddr = models.GenericIPAddressField(null=False, blank=False) time = models.DateTimeField(null=False, auto_now_add=True)