版權所有,轉載請註明出處:http://guangboo.org/2013/03/13/display-tree-with-django-template
django的template爲我們提供了大量的tag,filter等,並且我們可以自己定義tag和filter以滿足各自的需求。前一篇文章我們提供瞭如何在admin界面中顯示樹狀結構,現在我們要在web前提也要顯示,但是現實的效果不再是select的形式,而是使用ul,li標籤來暫時樹的層次,並且這種方式跟前篇文章的方式比起來,纔是真正的嵌套。以爲前者只是使用縮進來體現出層次感,本文將真實的使用嵌套的方式來實現層次性。
這裏再次定義一下Category類:
class Category(models.Model):
name = models.CharField('Category Name', max_length = 100, blank = False)
slug = models.SlugField('URL', db_index = True)
parent = models.ForeignKey('self', related_name='categories', null = True, blank = True)
那麼當我們要從數據庫中獲取樹的根節點時,可以這樣寫:
roots = Category.objects.filter(parent = None)
獲取節點node的所有子節點就可以這樣:
children = node.categories.all()
以上代碼是我們在web前臺實現樹的必要的代碼,也是準備工作。這裏我們通過定義自己的tag來實現樹的展示。django提供了一個簡單方法來實現tag的自定義,template.inclusion_tag方法,也可以叫修飾器。定義tag的代碼如下,tag的定義應該定義在app/templatetags目錄下,這裏py文件命名爲category_tags.py:
from django import template
from app.models import Category
template = template.Library()
@template.inclusion_tag("app/includes/category_tree_part.html")
def category_tree(cate):
return {'categories':cate.categories.all()}
代碼中category_tree_part.html爲樹節點的模板,該模板也非常的簡單,如下:
{% load category_tags %} {% if categories %}</pre> <ul>{% for cate in categories %} <li>{{ cate.name }} {% category_tree cate %}</li> {% endfor %}</ul> <pre class="brush:xml;">{% endif %}
代碼中load category_tags,就是前面定義tag的py文件名。這裏只是tag的模板,該模板需要在web的頁面中使用,使用的方式也與模板中的定義差不多,文件名爲category.html。如下:
{% extends "base.html" %} {% block content %} {% load category_tags %} {% category_tree categories %} {% endblock %}
是不是 很簡單啊,只有加載category_tags庫,然後調用tag:“category_tree categories”,這裏的categories當然是所有跟目錄裏。這就需要views裏面要將所有跟目錄的節點提取出來。如定義view名稱爲category_view,那麼定義爲:
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render_to_response
from app.models import Category
def category_view(request):
return render_to_response('app/category.html', {'categories':Category.objects.filter(parent = None)})
這樣就可以在web前臺展示tree了。