How to query reverse foreign key relationship in Django queryset?

TL;DR

class Post(models.Model):
    content = models.TextField()
    
class Comment(models.Model):
    comment_content = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments_rel')
    created_at = models.DateTimeField(auto_add_now=True)
    
    
# get all comments for a given post created in last 1 week
last_one_week_dt = timezone.now() - timezone.deltatime(days=7)
comments = Post.objects.filter(
    id= 10,
    comments_rel__created_at__gte=last_one_week_dt
)

# or use the below syntax
comments = Post.objects.get(id=10).comments_rel.filter(
	created_at__gte=last_one_week_dt
)

In the above example, we are able to fetch all the comments for id=1 and which are created in the last 1 week. Here are a couple of important concepts

  • related_name is added in the comments table which helps in establishing the reverse relationship used in the query.
  • You can use either of the syntaxes to perform the reverse query.
comments = Post.objects.filter(
    id= 10,
    comments_rel__created_at__gte=last_one_week_dt
)

Here we are filtering the id=10 from the Post table first and then we are using the comments_rel__created_at__gte=<datetime> query to filter from the comments table which has the post linked to the filtered item.

  • The other query
comments = Post.objects.get(id=10).comments_rel.filter(
	created_at__gte=last_one_week_dt
)

Here we are first filtering the post which has id=10 and then we shall filter the comments which were posted in the last 1 week.

For further details look into the official documentation.

Making queries | Django documentation | Django