我正在尝试在Django中创建层次结构视图,但我很难理解如何有效地使用QuerySet。
我最终的目标是显示以下课程的html页面:
Main Course 1 --- Child Course 1
--- Child Course 2
Main Course 2 --- Child Course 3
--- Child Course 4
每组课程都包含在div和样式等中。
在我的view.py文件中,我有以下内容:
class HierarchyView(generic.ListView):
template_name = 'curriculum/hierarchy.html'
def get_queryset(self):
return Offering.objects.all()
def get_context_data(self, **kwargs):
context = super(HierarchyView, self).get_context_data(**kwargs)
context['main'] = self.get_queryset().filter(course_type='M')
context['sub'] = self.get_queryset().filter(parent_code__in=context['main'])
return context
设置产品模型,以便parent_code是一个自引用外键(即任何课程可以是任何其他课程的孩子),如下所示:
...
parent_code = models.ForeignKey(
'self',
null=True,
blank=True,
on_delete=models.SET_NULL)
...
在我的html模板中,我有:
{% for mainoffering in main %}
<div>
<div>{{ mainoffering.course_name }}</div>
{% for offering in sub %}
<div>{{ offering.course_name }}</div>
{% endfor %}
</div>
{% endfor %}
然而,这导致所有儿童课程都出现在所有主要课程之下,无论他们是否真的是该课程的孩子,这显然不是我所追求的。
我还在学习Django的绳索,我很难找到任何用简单的英语解释我需要做什么的东西。请帮忙!
答案 0 :(得分:0)
我认为您需要更改模板以将每个子课程与其父课程相匹配。也许是这样的:
{% for mainoffering in main %}
<div>
<div>{{ mainoffering.course_name }}</div>
{% for offering in sub %}
{% if offering.parent_code == mainoffering %}
<div>{{ offering.course_name }}</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
答案 1 :(得分:0)
上下文[&#39; sub&#39;]将返回所有内容,不进行任何分组,排序等。您可以执行以下操作以获得所需的行为。
您可以执行相关的预取。
from django.db.models import Prefetch
offerings = Offering.objects.filter(course_type='M').prefetch_related(
Prefetch(
"courses_subset",
queryset=Offering.objects.filter(parent_code__in=offerings),
to_attr="sub"
)
)
for o in offerings:
print o.sub
你实际上可以在模型中创建一个方法并创建一个模板标签(我很可能会使用它)。
method in your Offering model
def get_child_courses(self):
child_courses = Offerings.objects.filter(parent_code=self.id)
return child_courses
template tag
@register.simple_tag
def get_child_courses(course):
return course.get_child_courses()
在你的模板中:
{% for mainoffering in main %}
<div>
<div>{{ mainoffering.course_name }}</div>
{% for offering in mainoffering|get_child_course %}
<div>{{ offering.course_name }}</div>
{% endfor %}
</div>
{% endfor %}
您可以按照accraze的建议将它们分组到模板中。我个人会选择第二个选项