For my Django + HTMX web app, I have the Like model, which belongs to either a blog instance or a comment instance. For the Blog and Comment models, I cache the like count with the like_count field. So anytime a like instance is saved or deleted, like_count is updated again, and I overrode the Like model's save() and delete() methods to handle this logic. However, like_count gets updated on the UI just fine when a new like instance is created, but not when it is deleted, and I have to reload the page for this to happen. What's the problem here? Here is my code:
#Instance field updates on model's save() method, but not on delete() method.
1 messages · Page 1 of 1 (latest)
# Comment and Blog models
class Comment(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
blog = models.ForeignKey(
"blog.Blog", on_delete=models.CASCADE, related_name="comments"
)
content = models.TextField()
liked_by = models.ManyToManyField(
settings.AUTH_USER_MODEL,
through="Like",
through_fields=("comment", "user"),
related_name="liked_comments",
blank=True,
)
like_count = models.PositiveIntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = CommentManager()
def __str__(self):
return self.content
class Blog(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="blogs"
)
title = models.CharField(max_length=100)
description = models.TextField()
picture = models.ImageField(blank=True)
saved_by = models.ManyToManyField(
settings.AUTH_USER_MODEL, related_name="saved_blogs", blank=True
)
liked_by = models.ManyToManyField(
settings.AUTH_USER_MODEL,
through="interaction.Like",
through_fields=("blog", "user"),
related_name="liked_blogs",
blank=True,
)
like_count = models.PositiveBigIntegerField(default=0)
comment_count = models.PositiveBigIntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = BlogQuerySet.as_manager()
def __str__(self):
return self.title
# Like model (the save and delete handle the logic)
class Like(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
blog = models.ForeignKey(
"blog.Blog", null=True, blank=True, on_delete=models.CASCADE
)
comment = models.ForeignKey(
Comment, null=True, blank=True, on_delete=models.CASCADE
)
class Meta:
constraints = [
CheckConstraint(
condition=(
Q(blog__isnull=False, comment__isnull=True)
| Q(blog__isnull=True, comment__isnull=False)
),
name="only_one_instance",
),
*[
UniqueConstraint(fields=["user", field], name=f"unique_like_{field}")
for field in ("blog", "comment")
],
]
def update_like_count(self):
instance = self.blog or self.comment
instance.like_count = instance.liked_by.count()
instance.save(update_fields=["like_count"])
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.update_like_count()
def delete(self, *args, **kwargs):
super().delete(*args, **kwargs)
self.update_like_count()