官方文档解释:
Recursively takes a self-nested list and returns an HTML unordered list – WITHOUT opening and closing <ul>
tags.
The list is assumed to be in the proper format. For example, if var
contains ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]
, then {{ var|unordered_list }}
would return:
<li>States
<ul>
<li>Kansas
<ul>
<li>Lawrence</li>
<li>Topeka</li>
</ul>
</li>
<li>Illinois</li>
</ul>
</li>
接下来我们就来实现上面的效果。
环境版本:
- python 2.7.10
- Django 1.8.5
首先在 models.py
添加代码:
#coding:utf-8
from django.db import models
class Area(models.Model):
name = models.CharField('名称', max_length=50, unique=True)
parent = models.ForeignKey('self', verbose_name='上级区域', null=True, blank=True, related_name='children')
class Meta:
db_table = 'area'
verbose_name = verbose_name_plural = '省/市/地区(县)'
def __unicode__(self):
return self.name
在 admin.py
添加代码:
from django.contrib import admin
from .models import Area
class AreaAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'parent')
admin.site.register(Area, AreaAdmin)
然后在后台添加数据。
按照官方文档的说法,显示时传递给模版的数据应该是下面这种格式:
['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]
所以我们需要写一个递归的工具函数。得到根节点,传递给 display
,然后把 display
函数生成的列表传递给模版:
from django.shortcuts import render_to_response
from .models import Area
def display(areas):
display_list= []
for area in areas:
display_list.append(area.name)
children = area.children.all()
if len(children) > 0:
display_list.append(display(children))
return display_list
def tree(request):
areas = Area.objects.filter(parent=None)
return render_to_response('tree.html', {'var': display(areas)})
最后在模板中添加:
{{ var|unordered_list }}
就可以看到显示效果了。
因为有时候需求不止这么简单,比如有时需要展现样式等等,unordered_list
就远远不够了。这个时候就需要使用 mptt
,请参照我的另一篇文章 使用 django-mptt 实现树形结构。