Django and Reverse M2M Relationship Filter#

While working on a project today, I learnt it's possible to execute reverse many-to-many relationship filters directly in Django.


from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

class Tag(models.Model):
    name = models.CharField(max_length=100)
    author = models.ForeignKey('Author', on_delete=models.CASCADE)

class Post(models.Model):
    title = models.CharField(max_length=100)
    tags = models.ManyToManyField(Tag)

In a scenario you need to find all posts with tags created by user, you can do the following:

post = Post.objects.filter(tags__author__name="author_name")

Much better and cleaner than chaining different querysets, right? SQL-wise, it also seems more efficient. The only thing that is missing there is the prefetch_related which again can be added to the queryset to avoid the N+1 problem:

post = Post.objects.filter(tags__author__name="tag_name").prefetch_related('tags_set__author')

The addition there is the _set which is the default name for the reverse relation lookups.