poll.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. def move(self, thread):
  28. if self.thread_id != thread.id:
  29. self.thread = thread
  30. self.category_id = thread.category_id
  31. self.save()
  32. self.pollvote_set.update(thread=self.thread, category_id=self.category_id)
  33. @property
  34. def ends_on(self):
  35. if self.length:
  36. return self.posted_on + timedelta(days=self.length)
  37. return None
  38. @property
  39. def is_over(self):
  40. if self.length:
  41. return timezone.now() > self.ends_on
  42. return False
  43. @property
  44. def thread_type(self):
  45. return self.category.thread_type
  46. def get_api_url(self):
  47. return self.thread_type.get_poll_api_url(self)
  48. def get_votes_api_url(self):
  49. return self.thread_type.get_poll_votes_api_url(self)
  50. def make_choices_votes_aware(self, user):
  51. if user.is_anonymous:
  52. for choice in self.choices:
  53. choice['selected'] = False
  54. return
  55. queryset = self.pollvote_set.filter(voter=user).values('choice_hash')
  56. user_votes = [v['choice_hash'] for v in queryset]
  57. for choice in self.choices:
  58. choice['selected'] = choice['hash'] in user_votes
  59. @property
  60. def has_selected_choices(self):
  61. for choice in self.choices:
  62. if choice.get('selected'):
  63. return True
  64. return False
  65. @property
  66. def view_choices(self):
  67. view_choices = []
  68. for choice in self.choices:
  69. if choice['votes'] and self.votes:
  70. proc = int(ceil(choice['votes'] * 100 / self.votes))
  71. else:
  72. proc = 0
  73. view_choices.append({
  74. 'label': choice['label'],
  75. 'votes': choice['votes'],
  76. 'selected': choice['selected'],
  77. 'proc': proc,
  78. })
  79. return view_choices