poll.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. from datetime import timedelta
  2. from math import ceil
  3. from django.conf import settings
  4. from django.contrib.postgres.fields import JSONField
  5. from django.db import models
  6. from django.utils import timezone
  7. class Poll(models.Model):
  8. category = models.ForeignKey('misago_categories.Category')
  9. thread = models.OneToOneField('misago_threads.Thread')
  10. poster = models.ForeignKey(
  11. settings.AUTH_USER_MODEL,
  12. blank=True,
  13. null=True,
  14. on_delete=models.SET_NULL,
  15. )
  16. poster_name = models.CharField(max_length=255)
  17. poster_slug = models.CharField(max_length=255)
  18. poster_ip = models.GenericIPAddressField()
  19. posted_on = models.DateTimeField(default=timezone.now)
  20. length = models.PositiveIntegerField(default=0)
  21. question = models.CharField(max_length=255)
  22. choices = JSONField()
  23. allowed_choices = models.PositiveIntegerField(default=1)
  24. allow_revotes = models.BooleanField(default=False)
  25. votes = models.PositiveIntegerField(default=0)
  26. is_public = models.BooleanField(default=False)
  27. @property
  28. def ends_on(self):
  29. if self.length:
  30. return self.posted_on + timedelta(days=self.length)
  31. return None
  32. @property
  33. def is_over(self):
  34. if self.length:
  35. return timezone.now() > self.ends_on
  36. return False
  37. @property
  38. def thread_type(self):
  39. return self.category.thread_type
  40. def get_api_url(self):
  41. return self.thread_type.get_poll_api_url(self)
  42. def get_votes_api_url(self):
  43. return self.thread_type.get_poll_votes_api_url(self)
  44. def make_choices_votes_aware(self, user):
  45. if user.is_anonymous():
  46. for choice in self.choices:
  47. choice['selected'] = False
  48. return
  49. queryset = self.pollvote_set.filter(voter=user).values('choice_hash')
  50. user_votes = [v['choice_hash'] for v in queryset]
  51. for choice in self.choices:
  52. choice['selected'] = choice['hash'] in user_votes
  53. @property
  54. def has_selected_choices(self):
  55. for choice in self.choices:
  56. if choice.get('selected'):
  57. return True
  58. return False
  59. @property
  60. def view_choices(self):
  61. view_choices = []
  62. for choice in self.choices:
  63. if choice['votes'] and self.votes:
  64. proc = int(ceil(choice['votes'] * 100 / self.votes))
  65. else:
  66. proc = 0
  67. view_choices.append({
  68. 'label': choice['label'],
  69. 'votes': choice['votes'],
  70. 'selected': choice['selected'],
  71. 'proc': proc
  72. })
  73. return view_choices