实现更简单的Facebook类型'喜欢'后端功能

时间:2018-06-04 22:26:24

标签: python django django-models

我正在使用Django制作的网站,我想实现一个facebook类型(或任何社交媒体类型)like按钮。我有一个user表和一个post表,我希望用户能够喜欢这些帖子。我对某些特定事情感到困惑:

  • 如何将用户信息与喜欢绑定,以便一个用户只能喜欢一次?

我目前的做法是:

  • 我正在考虑在post表格中创建一个新字段,比如post_likes,其中包含当前喜欢该帖子的用户列表。然后,在呈现' post'模板,我必须遍历所有用户(在post_likes字段中)以检查request.user是否喜欢帖子(在views.py中),并将该数据发送到模板(以更改ui like按钮到liked),但这种方法对我来说似乎很幼稚,也很慢。什么是更好的方法?

1 个答案:

答案 0 :(得分:2)

我们可以通过创建两个模型来实现这一目标:Post(实际上包含messageauthor等额外数据,和LikePostUser之间充当多对多关系:

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可以删除等等,我们对此没有多少控制权。是的,我们可以创建在LikeUser被删除(和创建)后触发的信号,但是仍然可能存在计算竞争条件等喜欢的数量的问题。因此,我建议定期更新喜欢的数量。