Abhijeet Khangarot
Abhijeet Khangarot

Reputation: 1567

Implement a facebook type simpler 'like' feature in backend

I am working on a website made in Django and i want to implement a facebook type (or any social media type) like button. I have a user table, and a post table, and i want users to be able to like the posts. I am confused about some particular things :

My current approach is:

Upvotes: 1

Views: 1270

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477170

We can do this by creating two models: Post (that will in reality contain extra data like the message, author, etc.), and Like that is acts as a many-to-many relation between a Post and a 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)

So the like(..) function is used to like a post (with as parameter the user). We can thus call somepost.like(someuser). It will fetch or create a new Like object that maps to the specific post and the specific user. In case the Like instance already existed, nothing happend, otherwise we increment the total_likes field that stores the total number of likes.

Perhaps you do not want to update this counter every time a user likes a post: after all, it creates some extra load on the server. In that case, the if created: part can be omitted, and we regularly should call Post.update_likes. This function will perform an aggregate per Post that counts the number of likes, and it will update the total_likes field.

Regardless whether you update total_likes constantly, it is better to every now and then update the total number of likes per post. Since other views, models, etc. can - given you the developers are not looking very strict to this - remove Like objects. Furthermore Users can be removed, etc. and we have not much control about that. Yes we can create signals that are triggered after Likes and Users are removed (and created), but still there can be problems with counting the number of likes like race conditions. Therefore I would advice to periodically update the number of likes.

Upvotes: 2

Related Questions