我正在尝试向 QuerySet 的元素添加一些额外的属性,以便我可以在模板中使用额外的信息,而不是多次访问数据库。让我举例说明,假设我们有带有外键到作者的书籍。

>>> books = Book.objects.filter(author__id=1)
>>> for book in books:
...     book.price = 2  # "price" is not defined in the Book model
>>> # Check I can get back the extra information (this works in templates too):
>>> books[0].price
2
>>> # but it's fragile: if I do the following:
>>> reversed = books.reverse()
>>> reversed[0].price
Traceback (most recent call last):
  ...
AttributeError: 'Book' object has no attribute 'price'
>>> # i.e., the extra field isn't preserved when the QuerySet is reversed.

因此,只要您不使用诸如 reverse() 之类的东西,就可以向 QuerySet 的元素添加属性。

我目前的解决方法是仅使用 select_related() 再次从数据库中获取我需要的额外信息,即使我已经在内存中。

有没有更好的方法来做到这一点?

最佳答案

出现错误是因为 qs.reverse() 产生了一个新的 QuerySet 实例,所以您没有反转旧的实例。

如果你想有一个基础 QS 来行动,你可以执行以下操作:

>>> augmented_books = Book.objects.extra(select={'price': 2))
>>> augmented_books[0].price
2
>>> augmented_books_rev = augmented_books.reverse()
>>> augmented_books_rev[0].price
2

当然 select 关键字可以复杂得多,实际上它几乎可以是任何可以适合 [XXX] 的有意义的 SQL 片段
SELECT ..., [XXX] as price, ... FROM ... WHERE ... (etc)

编辑

正如其他回复中所指出的,这种解决方案可能效率低下。

如果您确定从查询中获得 所有 Book 对象,那么您最好进行一次查询,将其存储到一个列表中,并最终反转结果列表。

另一方面,如果您正在获取表的“头”和“队列”,则进行两次查询会更好,因为您不会查询所有“中间”无用对象。

关于python - 有没有办法用额外的属性来增加 django QuerySets?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6999989/

10-13 02:32