JohnCastle
JohnCastle

Reputation: 569

Many to many unclear in django

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

Answers (1)

Rohan
Rohan

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

Related Questions