我想弄清楚如何使用 select_related
或 prefetch_related
从外键的另一端优化查询。例如:
假设我有一些模型,例如:
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")
如果我想打印所有
ProductImage
,我必须遍历所有产品,然后对于每个产品,遍历所有产品图像。但是,这会产生 O(n * m) 次数据库查询。for product in Product.objects.all():
print product.product_images.all()
我想知道是否有办法利用
select_related
或 prefetch_related
将这种查找减少到一两个查询。正如 Django 所记录的,我可以得到
select_related
当我选择 ProductImage
时工作.如您所见,添加 select_related
创建到产品表的 JOIN。>>> 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 ....
但是,我如何完成相反的操作?例如,我如何查询所有
Product
s 并让它在 ProductImage
上加入?执行以下操作似乎不起作用。Product.objects.select_related('product_images').query.sql_with_params()
在 Django 中可能有这样的事情吗?
感谢您的考虑。
最佳答案
这正是prefetch_related
做。
Product.objects.prefetch_related('product_images')
但是,使用
query.sql_with_params()
毫无意义。对此进行诊断:prefetch_related
做了两个查询,第二个不会出现在那里。您应该使用 django.db.connection.queries
检查 Django 正在执行的查询,或者甚至更好地使用 Django 调试工具栏向您展示。
关于Django 在外键上正确使用 select_related 或 prefetch_related,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22734475/