我有一个模型来管理类似的类别:
class Category(models.Model):
code = models.IntegerField()
name = models.CharField('name', max_length=200)
slug = models.SlugField(max_length=200)
parent = models.ForeignKey(
"self",
blank=True,
null=True,
related_name='subcategories')
现在,假设有3个类别: 猫A 猫B,父母是猫A. 猫C,父母是猫B
我想展示一个breacrumb,对于猫C,看起来像:
Home > Categories > Cat A > Cat B > Cat C
我现在可以得到:
Home > Categories > Cat B > Cat C
但我不知道如何获得父母的父母。 更一般地说,有没有办法构建这个面包屑动态地引导父母?
由于
答案 0 :(得分:2)
通过您的实施(称为'邻接列表'模式),您除了关注当前类别parent
之外别无其他选择,那么它的父母&#39 ;父母等:
class Category(models.Model):
code = models.IntegerField()
name = models.CharField('name', max_length=200)
slug = models.SlugField(max_length=200)
parent = models.ForeignKey(
"self",
blank=True,
null=True,
related_name='subcategories')
def get_parents(self):
parents = []
p = self.parent
while p:
parents.append(p)
p = p.parent
parents.reverse()
return parents
然后在你的模板中:
{% for parent in cat.get_parents %}
<a href="{{ p.get_absolute_url }}">{{ parent.label }}</a>
{% endfor %}
现在邻接列表模式虽然是最明显和最简单的实现,但是当你想要一次获得层次结构的整个部分时(例如,如果你想要给定节点的所有后代),效率非常低等),因为它需要很多查询。
在SQL中进行分层数据建模的效率更高(对于读取操作来说效率更高 - 它对写入操作的效率低得多),称为&#34;嵌套集合&# 34;图案。它实现起来要复杂得多,但好消息是,已经有一个可重用的django实现,django-mptt,它为你抽象出来。
除非你有数百名用户整天添加/删除/重新组织巨大的categeory树,否则我强烈建议你切换到mptt(嵌套集)。
此处有关SQL和分层数据的更多信息:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
在这里:What are the options for storing hierarchical data in a relational database?