【发布时间】:2018-09-30 10:37:43
【问题描述】:
将 Django 11 与 PostgreSQL 数据库一起使用。我有如下所示的模型。我正在尝试使用 Prefetch 对象和 prefetch_related 而不将其分配给属性来预取相关的查询集。
class Person(Model):
name = Charfield()
@property
def latest_photo(self):
return self.photos.order_by('created_at')[-1]
class Photo(Model):
person = ForeignKey(Person, related_name='photos')
created_at = models.DateTimeField(auto_now_add=True)
first_person = Person.objects.prefetch_related(Prefetch('photos', queryset=Photo.objects.order_by('created_at'))).first()
first_person.photos.order_by('created_at') # still hits the database
first_person.latest_photo # still hits the database
在理想情况下,调用person.latest_photo 不会再次访问数据库。这将允许我在列表显示中安全地使用该属性。
但是,正如代码中的 cmets 所述,当我尝试获取最新照片时,未使用预取的查询集。这是为什么呢?
注意:我尝试使用 Prefetch 的 to_attr 参数,这似乎有效,但是,这并不理想,因为这意味着我必须编辑 latest_photo 才能尝试使用预取属性。
【问题讨论】:
-
在
latest_photo方法中调用order_by('created_at')会创建一个新的查询集,因此不会使用预取的对象。另一种获取最新照片的方法是使用subquery。 -
有没有办法用 order_by 预取?另外,您能否详细说明使用子查询预取的情况?
-
我已经为您链接到子查询文档,我无法将查询写在脑海中。是的,您可以在
prefetch中使用order_by。问题是您在latest_photo方法中使用了不同/额外的order_by。 -
如果我想让你使用最初预取的 order_by 的结果,我该怎么做?
标签: python django query-optimization