Guest User

Untitled

a guest
Mar 8th, 2020
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.57 KB | None | 0 0
  1. class Votable(models.Model):
  2.     creator = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name="Criador")
  3.     creation_date = models.DateTimeField(editable=False, blank=True, null=True, verbose_name="Data de criação")
  4.     modified = models.DateTimeField(blank=True, null=True, verbose_name="Modificado")
  5.  
  6.     class Meta:
  7.         abstract = True
  8.  
  9.     def save(self, *args, **kwargs):
  10.         self.modified = timezone.now()
  11.         upvote_post = False
  12.         if not self.id:
  13.             self.creation_date = timezone.now()
  14.             upvote_post = True
  15.         obj = super(Votable, self).save(*args, **kwargs)
  16.         if upvote_post:
  17.             self.upvote_post(self.creator)
  18.         return obj
  19.  
  20.     def get_vote_object(self, user: UserProfile):
  21.         qs = Vote.objects
  22.         if type(self) is Post:
  23.             qs = qs.get(post=self, user=user)
  24.         elif type(self) is Comment:
  25.             qs = qs.get(comment=self, user=user)
  26.         return qs
  27.  
  28.     def upvote_post(self, user: UserProfile) -> None:
  29.         try:
  30.             vote = self.get_vote_object(user)
  31.             if vote.status == Vote.UPVOTE:
  32.                 # user already upvoted
  33.                 raise NotAllowedException("User already upvoted this post")
  34.             else:
  35.                 # user already voted and is changing the vote status
  36.                 vote.status = Vote.UPVOTE
  37.                 vote.save()
  38.         except Vote.DoesNotExist:
  39.             # user first time voting
  40.             if type(self) is Post:
  41.                 vote = Vote.objects.create(user=user, post=self, status=Vote.UPVOTE)
  42.             elif type(self) is Comment:
  43.                 vote = Vote.objects.create(user=user, comment=self, status=Vote.UPVOTE)
  44.  
  45.     def downvote_post(self, user: UserProfile):
  46.         try:
  47.             vote = self.get_vote_object(user)
  48.             if vote.status == Vote.DOWNVOTE:
  49.                 # user already downvoted
  50.                 raise NotAllowedException("User already downvoted this post")
  51.             else:
  52.                 # user already voted and is changing the vote status
  53.                 vote.status = Vote.DOWNVOTE
  54.                 vote.save()
  55.         except Vote.DoesNotExist:
  56.             # user first time voting
  57.             Vote.objects.create(user=user, votable=self, status=Vote.DOWNVOTE)
  58.  
  59.     def unvote_post(self, user):
  60.         try:
  61.             vote = self.get_vote_object(user)
  62.             vote.status = Vote.UNVOTE
  63.             vote.save()
  64.         except Vote.DoesNotExist:
  65.             # UserPostVote was never created.
  66.             raise NotAllowedException("User never voted on this post")
  67.  
  68.     def total_votes(self) -> Dict[str, int]:
  69.         qs = Vote.objects
  70.         if type(self) is Post:
  71.             qs = qs.filter(post=self)
  72.         elif type(self) is Comment:
  73.             qs = qs.filter(comment=self)
  74.         upvotes: int = qs.filter(status=Vote.UPVOTE).count()
  75.         downvotes: int = qs.filter(status=Vote.DOWNVOTE).count()
  76.         unvoted: int = qs.filter(status=Vote.UNVOTE).count()
  77.         return dict(upvotes=upvotes, downvotes=downvotes, unvoted=unvoted, total=upvotes - downvotes)
  78.  
  79.  
  80. class Post(Votable):
  81.     SELFPOST = "SELF"
  82.     LINKPOST = "LINK"
  83.     POST_TYPE_CHOICES = ((SELFPOST, "Texto"), (LINKPOST, "Link"))
  84.  
  85.     title = models.CharField(max_length=300, verbose_name="Título")
  86.     subreddit = models.ForeignKey(Subreddit, related_name="posts", on_delete=models.CASCADE)
  87.     post_type = models.CharField(max_length=4, verbose_name="Tipo de Post", choices=POST_TYPE_CHOICES)
  88.  
  89.     class Meta:
  90.         verbose_name = "Post"
  91.         verbose_name_plural = "Posts"
  92.  
  93.     @property
  94.     def content(self):
  95.         if self.post_type == self.LINKPOST:
  96.             return self.link_content
  97.         elif self.post_type == self.SELFPOST:
  98.             return self.self_content
  99.  
  100.     def __str__(self):
  101.         return f"b/{self.subreddit} • u/{self.creator} • {self.title}"
  102.  
  103.  
  104. class Comment(Votable):
  105.     post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments", verbose_name="Post")
  106.     text = models.TextField(max_length=10000, verbose_name="Comentário")
  107.     parent = models.ForeignKey('self', related_name="parent_comment", on_delete=models.PROTECT, null=True, blank=True)
  108.  
  109.     def __str__(self):
  110.         return f"u/{self.creator} • {self.post.title} • b/{self.post.subreddit.name}"
  111.  
  112.     class Meta:
  113.         verbose_name = "Comentário"
  114.         verbose_name_plural = "Comentários"
  115.  
  116.  
  117. class Vote(models.Model):
  118.     UPVOTE = "UPVOTE"
  119.     DOWNVOTE = "DOWNVOTE"
  120.     UNVOTE = "UNVOTE"
  121.     VOTE_STATUS_CHOICES = ((UPVOTE, "Upvoted"), (DOWNVOTE, "Downvoted"), (UNVOTE, "Unvoted"))
  122.  
  123.     user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name="Usuário")
  124.     status = models.CharField(max_length=10, choices=VOTE_STATUS_CHOICES, verbose_name="Estado")
  125.     post = models.ForeignKey(Post, null=True, on_delete=models.CASCADE)
  126.     comment = models.ForeignKey(Comment, null=True, on_delete=models.CASCADE)
  127.  
  128.     class Meta:
  129.         verbose_name = "Votos"
  130.         verbose_name_plural = "Votos de Usuário"
  131.         unique_together = ["post", "comment", "user"]
  132.  
  133.     def save(self, *args, **kwargs):
  134.         if not self.post and not self.comment:
  135.             raise ValidationError("Vote needs to have either self.post or self.comment")
  136.         if self.post and self.comment:
  137.             raise ValidationError("Vote can only have one of self.post or self.comment")
  138.         return super(Vote, self).save(*args, **kwargs)
  139.  
  140.     def __str__(self):
  141.         return f"u/{self.user.username} • {self.status}"
Advertisement
Add Comment
Please, Sign In to add comment