Wie kann ich eine Baumstruktur (rekursiv) mithilfe einer Django-Vorlage rendern?

StackOverflow https://stackoverflow.com/questions/32044

  •  09-06-2019
  •  | 
  •  

Frage

Ich habe eine Baumstruktur im Speicher, die ich mithilfe einer Django-Vorlage in HTML rendern möchte.

class Node():
  name = "node name"
  children = []

Es wird ein Objekt geben root das ist ein Node, Und children ist eine Liste von NodeS. root wird im Inhalt der Vorlage übergeben.

ich habe gefunden Das Es gibt eine Diskussion darüber, wie dies erreicht werden könnte, aber das Poster legt nahe, dass dies in einer Produktionsumgebung möglicherweise nicht gut ist.

Kennt jemand einen besseren Weg?

War es hilfreich?

Lösung

Ich denke, die kanonische Antwort lautet:"Nicht".

Was Sie stattdessen wahrscheinlich tun sollten, ist, die Sache in Ihrem Inneren zu entwirren Sicht Code, es ist also nur eine Frage der Iteration über (in|de)dents in der Vorlage.Ich denke, ich würde es tun, indem ich Einzüge und Einrückungen an eine Liste anhänge, während ich durch den Baum rekursiere, und dann diese „Reisebericht“-Liste an die Vorlage sende.(Die Vorlage würde sich dann einfügen <li> Und </li> aus dieser Liste die rekursive Struktur erstellen und sie „verstehen“.)

Ich bin mir auch ziemlich sicher, dass das rekursive Einbinden von Vorlagendateien wirklich eine Sache ist falsch Art und Weise, es zu tun ...

Andere Tipps

Benutzen with Template-Tag, ich könnte eine Baum-/rekursive Liste erstellen.

Beispielcode:

Hauptvorlage:Angenommen, „all_root_elems“ ist eine Liste einer oder mehrerer Baumwurzeln

<ul>
{%for node in all_root_elems %} 
    {%include "tree_view_template.html" %}
{%endfor%}
</ul>

tree_view_template.html rendert die verschachtelte Datei ul, li und Verwendungen node Vorlagenvariable wie folgt:

<li> {{node.name}}
    {%if node.has_childs %}
        <ul>
         {%for ch in node.all_childs %}
              {%with node=ch template_name="tree_view_template.html" %}
                   {%include template_name%}
              {%endwith%}
         {%endfor%}
         </ul>
    {%endif%}
</li>

Das ist vielleicht viel mehr als Sie brauchen, aber es gibt ein Django-Modul namens „mptt“ – dieses speichert eine hierarchische Baumstruktur in einer SQL-Datenbank und enthält Vorlagen für die Anzeige im Ansichtscode.Vielleicht findest Du dort etwas Nützliches.

hier ist der Link: django-mptt

Ich bin zu spät) alle benutzen so viel unnötig mit Tags, so mache ich recuesive:

in der Hauptvorlage:

<!-- lets say that menu_list is already defined -->
<ul>
    {% include "menu.html" %}
</ul>

dann in menu.html:

{% for menu in menu_list %}
    <li>
        {{ menu.name }}
        {% if menu.submenus|length %}
            <ul>
                {% include "menu.html" with menu_list=menu.submenus %}
            </ul>
        {% endif %}
    </li>
{% endfor %}

Ja, das schaffst du.Es ist ein kleiner Trick, den Dateinamen an { % include %} als Variable weiterzugeben:

{% with template_name="file/to_include.html" %}
{% include template_name %}
{% endwith %}

Django verfügt über einen integrierten Vorlagenhelfer für genau dieses Szenario:

https://docs.djangoproject.com/en/dev/ref/templates/builtins/#unordered-list

Ich hatte das gleiche Problem und habe ein Template-Tag geschrieben.Ich weiß, dass es noch andere Tags dieser Art gibt, aber ich musste sowieso lernen, benutzerdefinierte Tags zu erstellen :) Ich denke, es ist ziemlich gut geworden.

Lesen Sie die Dokumentation, um Anweisungen zur Verwendung zu erhalten.

github.com/skid/django-recurse

Mag niemand Diktate?Vielleicht fehlt mir hier etwas, aber es scheint die natürlichste Art zu sein, Menüs einzurichten.Wenn Sie Schlüssel als Einträge und Werte als Links verwenden, fügen Sie es in ein DIV/NAV ein und los geht's!

Von Ihrer Basis aus

# Base.html
<nav>
{% with dict=contents template="treedict.html" %}
 {% include template %}
{% endwith %}
<nav>

nenne das

# TreeDict.html
<ul>
{% for key,val in dict.items %}
 {% if val.items %}
  <li>{{ key }}</li>
  {%with dict=val template="treedict.html" %}
   {%include template%}
  {%endwith%}
 {% else %} 
  <li><a href="{{ val }}">{{ key }}</a></li>
 {% endif %}
{% endfor %} 
</ul>

Es wurde noch nicht die Standardeinstellung oder die bestellte Version ausprobiert, vielleicht haben Sie das getan?

korrigiere das:

root_comment.html

{% extends 'students/base.html' %}
{% load i18n %}
{% load static from staticfiles %}

{% block content %}

<ul>
{% for comment in comments %}
    {% if not comment.parent %}                   ## add this ligic
    {% include "comment/tree_comment.html" %}
    {% endif %}
{% endfor %}
</ul>

{% endblock %}

tree_comment.html

<li>{{ comment.text }}
    {%if comment.children %}
        <ul>
         {% for ch in comment.children.get_queryset %}     # related_name in model
              {% with comment=ch template_name="comment/tree_comment.html" %}
                   {% include template_name %}
              {% endwith %}
         {% endfor %}
         </ul>
    {% endif %}
</li>

zum Beispiel - Modell:

from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _


# Create your models here.
class Comment(models.Model):
    class Meta(object):
        verbose_name = _('Comment')
        verbose_name_plural = _('Comments')

    parent = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        parent_link=True,
        related_name='children',
        null=True,
        blank=True)

    text = models.TextField(
        max_length=2000,
        help_text=_('Please, your Comment'),
        verbose_name=_('Comment'),
        blank=True)

    public_date = models.DateTimeField(
        auto_now_add=True)

    correct_date = models.DateTimeField(
        auto_now=True)

    author = models.ForeignKey(User)

Ich hatte ein ähnliches Problem, allerdings hatte ich die Lösung zunächst mit JavaScript implementiert und kurz danach darüber nachgedacht, wie ich dasselbe in Django-Vorlagen gemacht hätte.

Ich habe das Serializer-Dienstprogramm verwendet, um eine Liste von Modellen in JSON umzuwandeln, und die JSON-Daten als Grundlage für meine Hierarchie verwendet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top