自动填充Django模板中树中每个级别的方法

时间:2017-05-25 18:59:06

标签: django django-models django-templates

我有一棵树有几层。纽约波士顿的Bucky表示不打破第一条编码规则 - 永远不要重复编码。

好吧,我在这里违反了这条规则。 Andcanät弄清楚如何避免这种情况。

我的计划也是能够单独崩溃每个分支。但首先我想填充树而不输入十个重复的代码。 这就是我打印树的方式。

{% block side-menu %}
    <div id="main-menu" role="navigation">
        <div id="main-menu-inner">
            {% load mptt_tags %}
            <ul class="navigation">
                {% for a in nodes %}
                    {% if a.item_parent is None %}
                        <li>
                            <i class="menu-icon glyphicon glyphicon-chevron-right"></i>
                            <span class="mm-text">{{ a.item_title }} - {{  a.get_descendant_count }}</span>
                            {% if a.get_descendant_count > 0 %}
                                {% for b in a.get_children %}
                                    {% if b.get_previous_sibling is none %}<ul class="children">{% endif %}
                                        {% if a.item_title == b.item_parent|stringformat:"s" %}
                                            <li>
                                                <i class="menu-icon glyphicon glyphicon-chevron-right"></i>
                                                <span class="mm-text">{{ b.item_title }} - {{  b.get_descendant_count }}</span>

                                                {% if b.get_descendant_count > 0 %}
                                                    {% for c in b.get_children %}
                                                        {% if c.get_previous_sibling is none %}<ul class="children">{% endif %}
                                                            <li>
                                                                <i class="menu-icon glyphicon glyphicon-chevron-right"></i>
                                                                <span class="mm-text">{{ c.item_title }} - {{  c.get_descendant_count }}</span>
                                                            </li>
                                                        {% if c.get_next_sibling is none %}</ul>{% endif %}
                                                    {% endfor %}
                                                {% endif %}
                                            </li>

                                        {% endif %}
                                    {% if b.get_next_sibling is none %}</ul>{% endif %}
                                {% endfor %}

                            {% endif %}
                        </li>
                    {% endif %}
                {% endfor %}
            </ul>
        </div>
    </div>
{% endblock %}

这是我的简单模型

from django.db import models
from mptt.models import MPTTModel, TreeForeignKey

class Item(MPTTModel):
    item_title = models.CharField(max_length=250)
    item_parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)


    class MPTTMeta:
        order_insertion_by = ['item_title']
        parent_attr = 'item_parent'

    def __str__(self):
        return self.item_title

1 个答案:

答案 0 :(得分:0)

我自己做了一个解决方案。我不知道这是否是一种正确的方法。或者如果性能下降。或者安全性很差。但它确实有效。

我会经历整个过程,对于那些像我一样的新手。正如你从我的问题中看到的,我安装了应用程序Django-mptt。这是构建树所必需的。

首先会有一个请求(从浏览器)到页面。 此请求已在URLS.PY中翻译。 在URLS中,请求被引导到VIEWS.PY中的正确视图。 在视图中,您将创建一些将传递给模板的逻辑。 该模板将向用户显示。

首先。如果您请求网址: 的 http://www.WEBSITE.se/items/

URLS.PY会看看您是否说明如果他们要求项目

该怎么做

<强> urls.py

from django.conf.urls import url

urlpatterns = [
    url(r'^item/$', views.item, name='item'),
]

这意味着网址请求项目/ 会被发送到 VIEWS.PY 和视图。这在代码中声明: views.item

<强> views.py

from django.shortcuts import render
from item.models import Item

    def item(request):
        all_root = Item.objects.filter(item_parent__isnull=True)

        context = {
            'nodes': all_root,
        }
        return render(request, 'item/index.html', context)

这里我正在对所有列item_parent为空的行进行数据库搜索。每个分支的根目录没有父分支。 我把对象放在一个名为'context'的字典中。我将名称设置为'nodes'。这将是我可以在模板中调用对象的名称。 然后我使用上下文作为资源渲染模板。如您所见,模板为'item / index.html'。

<强>的index.html

{% load mptt_tags %}
            <ul>
                {% for a in nodes %}

                        <li>
                            <i id="glyph_{{ a.id }}"></i>
                            <span class="mm-text" id="{{ a.id }}">{{ a.item_title }}</span>

                            <div style="display:none;" id="tree_{{ a.id }}" class=""></div>
                        </li>

                {% endfor %}
            </ul>

这是显示根项目的全部内容。如果您想知道数据库。那么这可以在我的问题中查看。你在那里看到模型。

所以,现在我希望能够与孩子一起扩展所有root。 因此我已经包含了Jquery并使用了Ajax。

所以我在模板中添加了这个脚本。

<强>的index.html

<script>
$(document).on("click",".mm-text", function(){
        console.log("Click Parent: "+ this.id);
        var parent_id = this.id;        
            $.ajax({
                type: 'POST',
                url: '/item/children/',
                data: {parent_id : parent_id, csrfmiddlewaretoken: '{{ csrf_token }}' },
                beforeSend: function() {
                    // If you want to anything before sending request
                    },
                success: function(response) {
                    $('#tree_'+ parent_id).html(response);
                    $('#tree_'+ parent_id).toggle("slow");                    
                },
                error: function(xhr, status, error) {
                    console.log("error");
                    // show error message
                }
            });
         }
    });
</script>

Ajax请求正在调用 / item / children / 因此我必须在urls.py中添加它。否则它不知道重定向的位置。

所以添加它以便它看起来像这样

<强> urls.py

 from django.conf.urls import url

    urlpatterns = [
        url(r'^item/$', views.item, name='item'),
        url(r'^item/children/$', views.get_children, name='get_children'),
    ]

您还需要查看网址重定向到的视图。所以在

中添加它

<强> views.py

def get_children(request):
    p_id = request.POST['parent_id']

    context = {
        'child_list':  Item.objects.filter(item_parent_id=p_id),
    }
    return_str = render_to_string('item/ax_get_children.html', context)
    return HttpResponse(return_str)

首先制作一个名为'ax_get_children.html'的模板。然后将此html作为HttpResponse发送回我们的'index.html'模板。

所以我们来看看

<强> ax_get_children.html

{% load mptt_tags %}
            <ul>
                {% for a in child_list %}

                        <li>
                            <i id="glyph_{{ a.id }}"></i>
                            <span class="mm-text" id="{{ a.id }}">{{ a.item_title }}  </span>                            
                            <div  style="display:none;" id="tree_{{ a.id }}" class=""></div>
                        </li>

                {% endfor %}
            </ul>

就是这样。再次。我不知道这是否是一个正确的方法。对于那些真正了解Django进行评估的人来说。我想说这可能不是一个好的解决方案。现在,我不知道更好。至少它有效。