有没有办法用额外的属性来增加django QuerySets? [英] Is there a way to augment django QuerySets with extra attributes?

查看:750
本文介绍了有没有办法用额外的属性来增加django QuerySets?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为QuerySet的元素添加一些额外的属性,所以我可以在模板中使用额外的信息,而不是多次点击数据库。让我举例说明一下,假设我们有一本带有ForeignKeys作品的书籍。

 >>> books = Book.objects.filter(author__id = 1)
>>>在书中的书籍:
... book.price = 2#价格未在书模型中定义
>>> #检查我可以收回额外的信息(这也适用于模板):
>>>书[0] .price
2
>>> #但它很脆弱:如果我执行以下操作:
>>> revers = books.reverse()
>>>反转[0] .price
追溯(最近的最后一次调用):
...
AttributeError:'Book'对象没有属性'price'
>> ; #即,当QuerySet相反时,extra字段不会被保留。

所以添加属性到QuerySet的元素可以工作,只要你不使用像reverse()。



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

有更好的方法吗?

解决方案

错误因为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 关键字可能会更复杂,实际上几乎任何有意义的SQL代码片段可以适合 c [XXX]

  SELECT ...,[XXX] as price,... FROM ... WHERE ...(etc)

编辑



在其他答复中,这种解决方案可能无效率。



如果您确定所有 Book对象查询,那么你最好做一个查询,将其存储到一个列表中,最后反转结果列表。



另一方面,如果你得到头和队列的表,使两个查询更好,因为你不会查询所有的中间无用的对象。


I'm trying to add some extra attributes to the elements of a QuerySet so I can use the extra information in templates, instead of hitting the database multiple times. Let me illustrate by example, assuming we have Books with ForeignKeys to Authors.

>>> 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.

So adding attributes to the elements of a QuerySet works, so long as you don't use things like reverse().

My current workaround is to just use select_related() to fetch the extra information I need from the database again, even though I already have in memory.

Is there a better way to do it?

解决方案

The error arises because qs.reverse() give rise to a new QuerySet instance, so you are not reversing the old one.

If you want to have a base QS on which to act you can do the following:

>>> 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

Of course the select keyword can be much more complex, in fact it can be almost any any meaningful SQL snippet that could fit the [XXX] in

SELECT ..., [XXX] as price, ... FROM ... WHERE ... (etc)

EDIT

As pointed out in other responses, this solution may be inefficient.

If you are sure to get all the Book objects from the query, then you 'd better make one query, store it into a list and eventually reverse the resulting list.

If, on the other hand, you are getting the "head" and the "queue" of the table, making two queries is better, because you won't query all the "middle" useless objects.

这篇关于有没有办法用额外的属性来增加django QuerySets?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆