Search code examples
pythondjangodjango-modelsdjango-ormdjango-related-manager

Get one related object in single request for Django ORM


I have this models

class Book(models.Model):
    title = models.CharField(max_length=255, blank=False, null=False)

class Like(models.Model):
    user = models.ForeignKey(User, related_name="like_user", blank=False, null=False)
    book = models.ForeignKey(Book, related_name="like_book", blank=False, null=False)
    class Meta:
        unique_together = ["user", "book"]

I want get all books and check if current user liked each book in single request

Book.objects.select_related('like_book').all()

won't work because of many results

Book.objects.prefetch_related('like_book').all()

will cache like_set but it will contain all likes for this Book. Not only one for this user.

In the end i want to have additional field is_liked

books = Book.objects.MAGIC_FETCH('like_book', user=self.request.user).all()
books[0].is_liked

Solution

  • * Updated to address comments *

    So roughly speaking, I think this is what you would use:

    Book.objects.annotate(is_liked=Case(When(like__user=self.request.user, then=True), default=False))