poll.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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", on_delete=models.CASCADE)
  9. thread = models.OneToOneField("misago_threads.Thread", on_delete=models.CASCADE)
  10. poster = models.ForeignKey(
  11. settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL
  12. )
  13. poster_name = models.CharField(max_length=255)
  14. poster_slug = models.CharField(max_length=255)
  15. posted_on = models.DateTimeField(default=timezone.now)
  16. length = models.PositiveIntegerField(default=0)
  17. question = models.CharField(max_length=255)
  18. choices = JSONField()
  19. allowed_choices = models.PositiveIntegerField(default=1)
  20. allow_revotes = models.BooleanField(default=False)
  21. votes = models.PositiveIntegerField(default=0)
  22. is_public = models.BooleanField(default=False)
  23. def move(self, thread):
  24. if self.thread_id != thread.id:
  25. self.thread = thread
  26. self.category_id = thread.category_id
  27. self.save()
  28. self.pollvote_set.update(thread=self.thread, category_id=self.category_id)
  29. @property
  30. def ends_on(self):
  31. if self.length:
  32. return self.posted_on + timedelta(days=self.length)
  33. @property
  34. def is_over(self):
  35. if self.length:
  36. return timezone.now() > self.ends_on
  37. return False
  38. @property
  39. def thread_type(self):
  40. return self.category.thread_type
  41. def get_api_url(self):
  42. return self.thread_type.get_poll_api_url(self)
  43. def get_votes_api_url(self):
  44. return self.thread_type.get_poll_votes_api_url(self)
  45. def make_choices_votes_aware(self, user):
  46. if user.is_anonymous:
  47. for choice in self.choices:
  48. choice["selected"] = False
  49. return
  50. queryset = self.pollvote_set.filter(voter=user).values("choice_hash")
  51. user_votes = [v["choice_hash"] for v in queryset]
  52. for choice in self.choices:
  53. choice["selected"] = choice["hash"] in user_votes
  54. @property
  55. def has_selected_choices(self):
  56. for choice in self.choices:
  57. if choice.get("selected"):
  58. return True
  59. return False
  60. @property
  61. def view_choices(self):
  62. view_choices = []
  63. for choice in self.choices:
  64. if choice["votes"] and self.votes:
  65. proc = int(ceil(choice["votes"] * 100 / self.votes))
  66. else:
  67. proc = 0
  68. view_choices.append(
  69. {
  70. "label": choice["label"],
  71. "votes": choice["votes"],
  72. "selected": choice["selected"],
  73. "proc": proc,
  74. }
  75. )
  76. return view_choices