【问题标题】:Tree Structure (Foreign Keys to itself) and templates树结构(自身的外键)和模板
【发布时间】:2018-04-13 13:45:55
【问题描述】:

我有一个类别的树结构。具有引用自身的外键的类别。

class Category(MetaData):
    parent = models.ForeignKey('self', blank=True, null=True, verbose_name='parent category', on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    description = models.TextField()

因为我不知道分类树的深度(不能用于)我需要使用递归函数:

def cat_for_parents(self, cat_obj):
                ...
                if cat_obj.parent_id:
                        p = cat_obj.parent
                        ...
                        self.cat_for_parents(p)

但是我如何在模板中实现函数以获得这样的东西(理论上无限递归循环):

<ul>
 <li>CategoryA
  <ul>
   <li>SubCategA1
     <ul>
       <li> Subcateg Subcateg B1
         <ul>
            <li> Subcateg SubCateg C1>
             <li> Subcateg SubCateg C2>
         <ul>
         <li> Subcateg Subcateg B2>
         ............. 

【问题讨论】:

  • 你应该考虑使用 django-mptt 来解决这个问题;它包括用于有效存储和检索树数据的数据库结构,以及用于递归渲染它的模板标签。
  • @Daniel Roseman - 谢谢,我会检查他们的代码;我更喜欢在我需要的地方和方式做我自己的自定义东西,包括 Django 版本,而不是在这种情况下使用第三方

标签: django django-templates foreign-keys


【解决方案1】:

我使用inclusion_tag 解决了这个问题。

例子:

model:

#just add related_name:
parent = models.ForeignKey('self', blank=True, null=True, related_name='subs', on_delete=models.CASCADE)

views.py:

categories = Category.objects.filter(parent=None)
# then pass it to template

template:

<ul>
    {% for category in categories %}
        <li>
            {{ category.name }}
            {% if category.parent.count > 0 %}
                {% tree_structure category %}
            {% endif %}
        </li>
    {% endfor %}
</ul>

自定义标签功能:

@register.inclusion_tag('path/to/tree_structure.html')
def tree_structure(category):
    subs = category.subs.all()
    return {"subs": subs}

tree_structure.html:

# remember to load your custom tags file
<ul>
    {% for sub in subs %}
        <li>
            {{ sub.name }}
            {% if sub.parent.count > 0 %}
                {% tree_structure sub %}
            {% endif %}
        </li>
    {% endfor %}
</ul>

它是如何工作的:

获取没有任何父级的类别并将它们发送到模板。 在模板中,我们使用 for 循环逐个渲染类别,然后在转到下一个类别进行渲染之前,检查该类别是否有任何子类别。 如果该类别有任何子类别,您会将类别传递给您的自定义模板标签,在那里您将获得该给定类别的所有子类别并将其传递给另一个模板文件以呈现它们,但在完成之前,请检查类别以查看该类别是否也有子类别,以及它是否只是在您完成第一个渲染之前再次调用自定义函数。它将一直持续到没有更多的类别和子类别,最后将包含第一个传递类别的所有子类别的完整模板传递给主模板,以便在其他类别之前呈现。

我无法自己测试此代码,因此可能存在一些小问题。

还可以查看自定义模板标签的文档: Custom template tags and filters

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 2011-11-25
    • 2015-12-21
    • 2022-01-05
    相关资源
    最近更新 更多