Search code examples
pythondjangodatabaseperformancemany-to-many

Django Like mechanism. Database performance question


I have CustomUser model and Post model. I consider adding a lightweight like mechanism to the posts.

What comes to my mind is defining a Like model in such fashion to connect the models to each other:

class LikeFeedback(models.Model):
   likingUser = models.ForeignKey(CustomUser)
   post_liked = models.ManyToManyField(Post)

But this design produces a new row in the database with each like.


Another option is to define CustomUser and Post models in a way that:

class Post(models.Model):
   ... 
   users_liked = models.ManyToManyField(CustomUser)

class CustomUser(models.Model):
   ... 
   posts_liked = models.ManyToManyField(Post)

I am not sure if this approach creates a new row or uses a different indexing mechanism, but it looks tidier.

In terms of DB performance what approach is the fastest? Do I need to define the ManyToMany connection in both models to speed up DB processes? Because 15 posts are to be displayed on the webpage at once and and with every post it is necessary to check if the visitor already liked the note. Also, with each like and takeback a write operation is to be performed on the DB.


Solution

  • I am not sure if this approach creates a new row or uses a different indexing mechanism, but it looks tidier.

    A ManyToManyField will create an extra table called a junction table [wiki] with ForeignKeys to the model where you define the ManyToManyField, and the model that you target with the ManyToManyField.

    You furthermore only need one ManyToManyField, otherwise you make two relations that act indepdently. You thus model this as:

    from django.conf import settings
    
    class Post(models.Model):
        # ... 
        likes = models.ManyToManyField(
            settings.AUTH_USER_MODEL,
            related_name='liked_posts'
        )
    
    class CustomUser(models.Model):
        # ... 
        # no ManyToManyField to Post

    Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.