15

I have following models:

class Product(models.Model):
    name = CharField(max_length=30)

class Store(models.Model):
    name = CharField(max_length=30)
    product = models.ManyToManyField(Product)

How to get Stores with product named product_name and also, get all the products (except the product with name product_name) ? Is it possible to make it in one query? In raw SQL it would be simple JOINs. Not sure how to implement it via Django.

chris Frisina
  • 19,086
  • 22
  • 87
  • 167
sunprophit
  • 1,639
  • 4
  • 16
  • 39

3 Answers3

25

You can actually do these things with Django due to it's lazy queryset evaluation. Django's in field lookup accepts both lists and querysets. The following will create a nested SQL code:

products = Product.objects.filter(store_set__in=stores_qs)
stores_qs = Store.objects.filter(product__name='product_name')

Here are the Django in docs.

chris Frisina
  • 19,086
  • 22
  • 87
  • 167
miki725
  • 27,207
  • 17
  • 105
  • 121
9

You should be able to filter the stores based on an attribute of Product, and then prefetch_related of the retrieved objects.

Store.objects.filter(product__name="product_name").prefetch_related('product')

This should hit the database the fewest times to achieve what you are looking for - twice.

Further documentation can be found here.

jondykeman
  • 6,172
  • 3
  • 23
  • 22
2

Get Stores with product named "product_name" :

Store.objects.filter(product__name='product_name')

Get all the products except the product with name "product_name":

Product.objects.exclude(name='product_name')
jnishiyama
  • 377
  • 2
  • 8
UnLiMiTeD
  • 1,000
  • 1
  • 9
  • 17