Столкнулся с необходимостью вывести дерево элементов (список категорий с подкатегориями). Глубина вложенности изначально не ограниченна. Решение задачи дальше.
Древовидные данные
Итак, есть модель:
class Category(models.Model):
master = models.ForeignKey('self',related_name='translations',null=True,blank=True)
title = models.CharField(max_length=250)
parent = models.ForeignKey('self',blank=True,null=True)
description = models.TextField()
cdate = models.DateTimeField(auto_now_add=True)
mdate = models.DateTimeField(auto_now=True)
language = models.CharField(max_length=2, choices=settings.LANGUAGES)
def __unicode__(self):
return self.title
Как видно, поле parent позволяет указать родителя и таким образом создать вложения неограниченной глубины.
Теперь возникает вопрос - как в шаблоне организовать рекурсивный вывод данных. Я пропущу все прелюдии и ошибочные пути, которыми я шел, такие как get_levels_count(), get_level_n(n) и т.п. В конечном итоге нужную функциональность удалось организовать при помощи шаблонных тегов.
Шаблонный тег для рекурсивного вывода данных
Начнем писать свой тег.
1. В папке своего приложения создаем папку templatetags, в ней создаем пустой файл __init__.py и файл category_tree.py. В последнем собственно и будет наш тег.
2. В файл category_tree.py вписываем следующее:
from django import template
from shop.products.models import Category
register = template.Library()
@register.inclusion_tag('products/templatetags/category_tree.html')
def category_tree(context,category):
children = Category.objects.filter(parent=category)
return {'category': category, 'children' : children,}
3. В шаблон products/templatetags/category_tree.html пишем следующее:
{% load category_tree %}
<li>{{ category.title }}
<ul>
{% for child in children %}
<li>{% category_tree child %}</li>
{% endfor %}
</ul>
</li>
4. Ну и наконец, в главный шаблон, в котором нужно вывести дерево:
{% load category_tree %}
<ul>
{% for category in categories %}
<li>{% category_tree category %}</li>
{% endfor %}
</ul>
Собственно, это все. Виват, django!
{ 1 } Trackback
[...] Original post by solshark [...]
Post a Comment