from __future__ import annotations from django.core.exceptions import ValidationError from django.db import models class Comment(models.Model): article = models.ForeignKey("blog.ArticlePage", on_delete=models.CASCADE, related_name="comments") parent = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE, related_name="replies") author_name = models.CharField(max_length=100) author_email = models.EmailField() body = models.TextField(max_length=2000) is_approved = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) ip_address = models.GenericIPAddressField(null=True, blank=True) def clean(self) -> None: if self.parent and self.parent.parent_id is not None: raise ValidationError("Replies cannot be nested beyond one level.") def get_absolute_url(self): return f"{self.article.url}#comment-{self.pk}" def __str__(self) -> str: return f"Comment by {self.author_name}" class CommentReaction(models.Model): comment = models.ForeignKey(Comment, on_delete=models.CASCADE, related_name="reactions") reaction_type = models.CharField(max_length=20, choices=[("heart", "❤️"), ("plus_one", "👍")]) session_key = models.CharField(max_length=64) created_at = models.DateTimeField(auto_now_add=True) class Meta: constraints = [ models.UniqueConstraint( fields=["comment", "reaction_type", "session_key"], name="unique_comment_reaction_per_session", ) ] def __str__(self) -> str: return f"{self.reaction_type} on comment {self.comment_id}"