2

Assume my models:

model book 
    charfield name

model review
    charfield bookname

Is there a way to filter/exclude the books with review count zero? I looked this up throughly on stackoverflow but couldn't find an answer. This is not a homework question. I have a queryset approx. size around 200,000, from which I concluded that it is not smart to filter by converting the queryset to a python list, filter, then convert back. Can someone help me with this? Thanks

3
  • 1
    Is there a reason your Review model has a charfield with a book name instead of a foreign key directly to the correct Book object? The filter would be easier to do if the models were actually linked. Also, it isn't clear from your question whether you want to keep or exclude the books with no reviews from your queryset. Commented Jan 24, 2017 at 5:11
  • @ChidG thanks for the reply. Say I have a huge amount of books and reviews, I was thinking that linking a review to a book every time when I add it would take too long because of the lookup time. Should linking them be the way to do it in favor of this? Commented Jan 24, 2017 at 14:49
  • Linking them via foreign key is definitely the standard, best practice way of solving this problem. The time to do a database join between the two tables is going to be far less trouble than the other problems caused by not linking them. For example, your database would need to be much larger (in disk space), because the book names will all need to be stored in multiple places. And what happens when you have more than one book with the same name? Or when someone enters a book name incorrectly in a review? I would suggest you read up a little on relational database design. Commented Jan 25, 2017 at 1:59

2 Answers 2

3

Because I strongly recommend changing your models to include a foreign key from review to book (for the many other benefits of doing that) rather than attempting to solve the exact problem you've asked about, I'm going to give you a hint on how to write your models with a foreign key and then how to solve the problem you've asked about in the context of a foreign key relationship.

Here are the new models I think you should write:

from django.db import models

class Book(models.Model):
    name = models.Charfield()

class Review(models.Model):
    book = models.ForeignKey(Book, related_name='reviews')

Then, to filter for all books having any reviews you could do:

books_with_reviews = Book.objects.filter(reviews__isnull=False).distinct()

Or for books without reviews:

Book.objects.filter(reviews__isnull=True).distinct()
Sign up to request clarification or add additional context in comments.

Comments

1

First, you can query list of book which has review, and then get compliment by using django exclude

bookname_has_review = Review.objects.all().distinct().values_list('bookname', flat=True)
book_not_have_review = Book.objects.all().exclude(name__in=bookname_has_review)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.