Reputation: 569
Models :
class Store(models.Model):
name = models.CharField(max_length=100)
greatStore = models.BooleanField()
class Book(models.Model):
stores = models.ManyToManyField(Store)
name = models.CharField(max_length=200,unique=True)
fantasticBook = models.BooleanField()
I want get the list of all the books which are in great stores. Reading the documentation, it says : https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships that I should write :
myBooks =Book.objects.filter(stores__greatStore=True)
but this merely does a JOIN with a Store.greatStore==TRUE which is NOT what I want !
For instance if I have 2 stores (both are great stores) and one book in my database which belongs to the 2 stores, myBooks is going to have 2 elements : twice the same book.
I wanted the collection of books which have at least one great store, not the first element of couples (b,s) which verifies (s belongs to b.stores and s.greatStores==true)
EDIT :
Why I think Django's API is misleading : Let's keep the same example : 2 great stores and book (fantasticBook==true) which belongs to both store. If you run the request :
myBooks = Book.objects.all()
you get only one result : the only book that exists. If you run the request :
myBooks = Book.objects.filter(coolBook=True)
you get only one result : the only book that exists. If you run the request :
myBooks = Book.objects.filter(stores__greatStore=True)
It seems to mean that you get the collection of books which have at least one great store but this is not what we get because myBooks has 2 results.
Upvotes: 0
Views: 73
Reputation: 53326
You can use distinct()
which will give you unique results for Book
like:
myBooks =Book.objects.filter(stores__greatStore=True).distinct()
Upvotes: 1