I'm trying to figure out how to use select_related
or prefetch_related
to optimize a query from the other end of a foreign key. For example:
Say I have some models such as the following:
class Product(models.Model):
name = models.CharField(max_length=50)
class ProductImage(models.Model):
image = models.ImageField(upload_to="images")
product = models.ForeignKey("myapp.Product", related_name="product_images")
If I want to print all of the ProductImage
, I have to iterate through all of the products and then, for each product, iterate through all of the product images. However, this produces O(n * m) database queries.
for product in Product.objects.all():
print product.product_images.all()
I'm wondering if there is a way to utilize select_related
or prefetch_related
to reduce this lookup to one or two queries.
As documented by Django, I can get select_related
to work when I select ProductImage
. As you can see, adding the select_related
creates a JOIN to the product table.
>>> ProductImage.objects.all().query.sql_with_params()
(u'SELECT "myapp_productimage"."id", ... FROM "myapp_productimage" ....
>>> ProductImage.objects.select_related('product').query.sql_with_params()
(u'SELECT "myapp_productimage"."id", ... FROM "myapp_productimage" LEFT OUTER JOIN ....
However, how do I accomplish the reverse? For example, how do I query all of the Product
s and have it JOIN on the ProductImage
s? Doing something like the following doesn't seem to work.
Product.objects.select_related('product_images').query.sql_with_params()
Is something like this possible in Django?
Thanks for your consideration.