我正在使用Django制作的网站,我想实现一个facebook类型(或任何社交媒体类型)like
按钮。我有一个user
表和一个post
表,我希望用户能够喜欢这些帖子。我对某些特定事情感到困惑:
我目前的做法是:
post
表格中创建一个新字段,比如post_likes
,其中包含当前喜欢该帖子的用户列表。然后,在呈现' post'模板,我必须遍历所有用户(在post_likes
字段中)以检查request.user
是否喜欢帖子(在views.py中),并将该数据发送到模板(以更改ui like
按钮到liked
),但这种方法对我来说似乎很幼稚,也很慢。什么是更好的方法? 答案 0 :(得分:2)
我们可以通过创建两个模型来实现这一目标:Post
(实际上包含message
,author
等额外数据,和Like
在Post
和User
之间充当多对多关系:
class Post(models.Model):
total_likes = models.IntegerField(default=0)
likes = models.ManyToManyField(User, through='app.Like')
def like(self, user):
_, created = Like.objects.get_or_create(user=user, post=self)
if created:
self.total_likes += 1
self.save()
@classmethod
def update_likes(cls):
cls.objects.annotate(total=Count('likes')).update(total_likes=F('total'))
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
因此like(..)
函数用于喜欢一个帖子(用作参数的用户)。因此,我们可以致电somepost.like(someuser)
。它将获取或创建一个新的Like
对象,该对象映射到特定的post
和特定的user
。如果Like
实例已经存在,则不会发生任何事情,否则我们会增加存储喜欢总数的total_likes
字段。
每次用户喜欢帖子时,您可能不想更新此计数器:毕竟,它会在服务器上产生一些额外的负载。在这种情况下,if created:
部分可以省略,我们经常应该调用Post.update_likes
。此函数将执行每Post
的聚合,计算喜欢的数量,并将更新total_likes
字段。
无论您是否经常更新total_likes
,最好立即更新每个帖子的喜欢总数。由于其他视图,模型等可以 - 给你开发人员看起来不是很严格 - 删除Like
对象。此外User
可以删除等等,我们对此没有多少控制权。是的,我们可以创建在Like
和User
被删除(和创建)后触发的信号,但是仍然可能存在计算竞争条件等喜欢的数量的问题。因此,我建议定期更新喜欢的数量。