有两种型号:
class Subject(Model):
categories = ManyToManyField(Category, related_name='subjects')
class Category(Model):
parent = ForeignKey('self', related_name='subcategories')
这应该被翻译成以下剩余输出:
[
{
...,
"categories": [
{"subcategories": [{}, {} ... {}]},
{"subcategories": [{}, {} ... {}]}
],
},
{
...,
"categories": [
{"subcategories": [{}, {} ... {}]},
{"subcategories": [{}, {} ... {}]}
],
}
]
问题是为每个类别设置一组子类别,这些子类别与祖先主题存在多对多关系。
到目前为止,我认为查询集应该是这样的:
Subject.objects.prefetch_related(
Prefetch(
lookup="categories",
queryset=Category.objects.filter(parent__isnull=True)
.prefetch_related(
Prefetch(
lookup="subcategories",
queryset=Subquery(
Category.objects.filter(
parent__pk=OuterRef("pk"),
subjects__id__in=OuterRef(OuterRef("pk")),
)
)
)
)
.distinct(),
),
)
但这给出了错误:
AttributeError: 'Subquery' object has no attribute '_chain'
查询集出了什么问题。正确的做法是什么?
您尝试在单个语句中执行的方式既不简洁也不高效。 更好的方法是使用递归函数,然后安排响应。 你可以看看以下。
def get_sub_categories(category):
"""
This is a function which we are using recursively to get all subcategories for a catefgory
"""
category_data = {'name': category.name}
subcategories = category.subcategories.all()
if subcategories:
category_data['subcategories'] = [get_sub_categories(subcategory) for subcategory in subcategories]
return category_data
使用上述功能,您可以获得给定主题的所需响应。
subject = Subject.objects.get(id=subject_id)
categories = subject.categories.all()
data = [get_sub_categories(category) for category in categories]
您的数据将如下所示,您可以进一步进行调整以根据您的需要获取所需的字段
[
{
"name": "Government Exam",
"subcategories": [
{
"name": "SSC",
"subcategories": [
{
"name": "Physical",
"subcategories": [
{
"name": "Body 1"
},
{
"name": "Body 2"
}
]
},
{
"name": "Written",
"subcategories": [
{
"name": "Socialogy"
},
{
"name": "Enviromental"
}
]
}
]
},
{
"name": "NDA"
}
]
}
]