在Django中如何获取查询集的所有子项?

7

我有一个查询集结果,比如说,动物,其中包含一系列动物。这些动物有子类别,我想要获取所有的子类别。例如:

对于单个动物,我可以使用 animal.categories 来获取其分类信息,这个方法是可行的。现在,我希望以某种方式实现以下操作:

categories = animals.categories

动物是查询集时,我该如何实现这一点?
3个回答

9

没有办法绕过查询集的迭代,但是您可以使用prefetch_related来加快速度:

all_animals = Animals.objects.prefetch_related('categories')
categories = [animal.categories.all() for animal in all_animals]

我在代码中稍后使用了values_list,但对于categories这个字段没有起作用 - wasimbhalli
我使用了 categories.values_list('user_id', flat=True),但是出现了错误:'list' object has no attribute 'values_list'。 - wasimbhalli

6

有两种选择:

1)按照您的问题要求,您只能执行以下操作:

categories=[]
for aninmal in animals:
    categories.extend(animal.categories.all())

2) 然而,我会使用类别运行一个新的查询(我不知道您的确切数据模型和措辞,但我认为您明白我的意思)。

categories=Category.filter(animals__in=animals).all()

2

(基础: 如果animals.categories返回的是一个查询集,那么意味着categories与animal有多对一的关系。默认名称(category_set)已更改为categories)

在我看来,你的主要查询应该是类别查询而不是动物查询。假设你像这样获取动物:

Animals.objects.filter(name__startswith='A')

您可以通过以下查询获取这些动物的类别。
Category.objects.filter(animal__name__startswith='A')

你可以使用此查询获取动物。
Category.objects.filter(animal__name__startswith='A').select_related('category')

但我建议为类别和动物使用单独的查询(这样更节省内存,但需要进行两次查询)。

注意:如果您真的在使用一对多关系,应考虑将其更改为多对多关系。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接