预取对象不使用order_by queryset

时间:2018-04-19 20:00:46

标签: python django query-optimization

将Django 11与PostgreSQL db一起使用。我有如下所示的模型。我尝试使用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不会再次访问数据库。这将允许我在列表显示中安全地使用该属性。 但是,正如代码中的注释所述,当我尝试获取最新照片时,未使用预取查询集。那是为什么?

注意:我已尝试使用to_attr Prefetch的{​​{1}}参数,但这似乎有效,但是,它并不理想,因为它意味着我必须编辑latest_photo以尝试使用预取属性。

1 个答案:

答案 0 :(得分:0)

问题在于切片,它会创建一个不同的查询。

你可以这样解决:

    ...

    @property
    def latest_photo(self):
        first_use_the_prefetch = list(self.photos.order_by('created_at'))
        then_slice = first_use_the_prefetch[-1]
        return then_slice

如果你想尝试,就不可能在Prefetch中使用切片(查询=这里没有切片......)(在Django跟踪器的某个地方有一个wontfix功能请求)。 / p>