Trying to render in html parent categories and under each parent to render it’s childs,
the result i get parents right but it repeats only childs for one parent under all of parents.
i guess the problem in the context because i get it in for loop,
but when i move it out of loop it cannot see childs.
how can i get childs and also parents in same context.
View:
def categories(request, parent_category=None):
parent_categories_list = Category.objects.filter(parent=None)
for parent_category in parent_categories_list:
child_categories_list = Category.objects.filter(parent=parent_category)
return {
'parent_categories_list': parent_categories_list,
'child_categories_list': child_categories_list,
}
HTML:
{% for parent_category in parent_categories_list %}
<div class="column">
<h4 class="ui header">
<a href="{{ parent_category.get_absolute_url }}">
{{ parent_category.name }}
</a>
</h4>
<div class="ui link list">
{% for child_category in child_categories_list %}
<a class="item" href="{{ child_category.get_absolute_url }}">
{{ child_category.name }}
</a>
{% endfor %}
<div>
</div>
{% endfor %}
This loop is only going to execute 1 time. Your return statement is inside the loop, and so for the first time through the loop, it’s going to return that dict and exit the loop.
It appears from your template that what you want is to render the top level Category objects along with the objects that directly refer to it. You don’t need a separate query.
What you’re really trying to do here is follow the foreign key relationship backwards. You have a Category that has a set of objects related to it by a foreign key. You want to access that set of related objects.
great thanks ken but how about the return if i need to return both of parent_categories_list and child_categories_list how to pass them into one context, Or should i have to make it in two functions.
i tried to indent return statement under the For loop but it there is no parent_categories_list in that case.
is it possible to pass both in same context.
my last function:
Cool! Now having said that, I will point out a performance enhancement available to you.
If you were to follow this being run, you would see that your view is executing a query for your parent_categories_list plus a query for each parent category to retrieve the related child category list.
Django provides a function named prefetch_related, that retrieves all of the child categories once and then associates each with their respective parent.
So in your case, it would probably look something like this: parent_categories_list = Category.objects.filter(parent=None).prefetch_related('category')
You would then see that this view only executes two queries for the page instead of “N + 1”.