gpt4 book ai didi

python - 有没有办法用额外的属性来增加 django QuerySets?

转载 作者:太空宇宙 更新时间:2023-11-03 13:51:46 24 4
gpt4 key购买 nike

我正在尝试向 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() 再次从数据库中获取我需要的额外信息,即使我已经在内存中了。

有更好的方法吗?

最佳答案

这是一个老问题,但我会添加我的解决方案,因为我最近需要它。

理想情况下,我们可以为 QuerySet 使用某种代理对象。然后,我们的代理版本将在迭代期间进行更改。

很难涵盖所有可能的场景,QuerySet 对象有点复杂并且有多种不同的使用方式。但是对于在最后一分钟添加属性因为发送到模板(或通用 View )的简单情况,以下可能有效:

class alter_items(object):

def __init__(self, queryset, **kwargs):
self.queryset = queryset
self.kwargs = kwargs

# This function is required by generic views, create another proxy
def _clone(self):
return alter_items(queryset._clone(), **self.kwargs)

def __iter__(self):
for obj in self.queryset:
for key, val in self.kwargs.items():
setattr(obj, key, val)
yield obj

然后像这样使用它:

query = alter_items(Book.objects.all(), price=2)

因为它不是真正的代理,你可能需要根据它的使用方式做进一步的修改,但这是粗略的做法。如果有一种简单的方法可以在 Python 中使用新样式类创建代理类,那就太好了。如果您想使用更完整的实现,外部库 wrapt 可能会有用

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

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com