树结构(本身的外键)和模板 [英] Tree Structure (Foreign Keys to itself) and templates

查看:91
本文介绍了树结构(本身的外键)和模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类别的树结构。

I have a tree structure for Categories. Categories with a Foreign key that is referring to itself.

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()

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

Because I don't know the depth of the categories tree(can't use for) I need to use a recursive function:

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

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

But how I implement the function in the template to get something like this(to theoretically infinite recursive loop):

<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>
         ............. 


推荐答案

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

I used inclusion_tag to solve this.

示例:

模型

#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

模板

<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循环来逐一渲染类别,然后转到下一个类别进行渲染,然后检查该类别是否没有任何子项。
如果该类别有任何子类别,您将将该类别传递到自定义模板标签,在那里您将获得该给定类别的所有子类别,并将其传递到另一个模板文件以进行渲染,但要先完成,请检查该类别以查看该类别是否也包含子类别,并且在您完成渲染第一个类别之前是否再次调用自定义函数。直到没有更多的类别和子类别,最后将一个完整的模板以及第一个通过的类别的所有子类别传递到主模板,以便在其他类别之前呈现。

Getting the categories without any parent and send them to template. In template we use a for loop to render categories one by one and before going to next category to render, you check if that category hast any subs. If there was any subs for that category, you will pass the category to your custom template tag and there you will get all the sub categories for that given category and pass it to another template file to render them but before finishing it, check for that category to see if that one has sub categories too or not and if it does just call custom function again before u finish rendering the first one. it will goes till there is no more category and sub categories and at the end passes a complete template with all the sub categories for the first passed category to the main template to render before other categories.

我自己无法测试此代码,因此可能会有小问题。

I couldn't test this code myself so there might be small issues.

也请查看文档中的自定义模板标签:
自定义模板标签和过滤器

Also check the documentation for custom template tags: Custom template tags and filters

这篇关于树结构(本身的外键)和模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆