Comment puis-je rendre à une structure d'arbre (récursif) à l'aide d'un modèle django?

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

  •  09-06-2019
  •  | 
  •  

Question

J'ai une arborescence dans la mémoire que je voudrais rendre en HTML à l'aide d'un modèle Django.

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

Il y aura un certain objet root c'est un Node, et children une liste de Nodes. root seront passés dans le contenu du modèle.

J'ai trouvé cette une discussion de la façon dont cela pourrait être réalisé, mais l'affiche suggère que c'est peut-être pas bien dans un environnement de production.

Quelqu'un sait d'une meilleure façon?

Était-ce utile?

La solution

Je pense que la réponse canonique est:"Ne pas".

Ce que vous devriez faire à la place est de démêler la chose dans votre vue code, c'est juste une question de parcourir (en|de), les bosses dans le modèle.Je pense que je le ferais en ajoutant des tirets et dedents à une liste de tout recursing par le biais de l'arbre, puis l'envoi de ce "carnet de route" de la liste pour le modèle.(le modèle puis insérez <li> et </li> à partir de cette liste, la création de la structure récursive avec la "compréhension" il.)

Je suis aussi assez sûr de manière récursive, y compris les fichiers de modèle est vraiment un mal façon de le faire...

Autres conseils

À l'aide de with balise de modèle, je pourrais faire d'arbre/récursif de la liste.

Exemple de code:

template principal:en supposant que "all_root_elems' est la liste d'un ou de plusieurs de la racine de l'arbre

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

tree_view_template.html rend le imbriquée ul, li et utilise node variable de modèle comme ci-dessous:

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

cela peut être de façon plus que vous avez besoin, mais il y a un django module appelé "mptt' - il stocke une arborescence hiérarchique, dans une base de données sql, et comprend des modèles pour l'affichage dans le code de la vue.vous pourriez être en mesure de trouver quelque chose d'utile là.

voici le lien : django-mptt

Je suis en retard) Tous vous utilisez tellement inutile avec balises, c'est comment je le fais recuesive:

dans le template principal:

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

puis dans 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 %}

Oui, vous pouvez le faire.C'est un petit truc, en passant le nom du fichier à {% include %} comme une variable:

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

Django a construit dans le template d'aide pour ce scénario exact:

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

J'ai eu le même problème et j'ai écrit une balise de modèle.Je sais qu'il existe d'autres balises comme ceci, mais j'ai besoin d'apprendre à faire de la coutume balises de toute façon :) je pense que ça s'est avéré assez bien.

Lire la docstring pour les instructions d'utilisation.

github.com/skid/django-recurse

Pas un comme les dicts ?J'ai peut-être raté quelque chose ici, mais il semble que la façon la plus naturelle pour les menus de configuration.À l'aide des touches comme les entrées et les valeurs que les liens de la pop dans un DIV/NAV et vous allez loin !

À partir de votre base de

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

appel de cette

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

Il n'ai pas essayé la valeur par défaut ou commandés mais peut-être que vous avez ?

corriger ce:

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>

par exemple - modèle:

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)

J'ai eu un problème similaire, cependant j'avais d'abord mis en œuvre la solution à l'aide de JavaScript, et seulement ensuite examiné comment j'aurais fait la même chose dans des modèles django.

J'ai utilisé le sérialiseur utilitaire pour transformer une liste de modèles en json, et utilisé les données json comme une base de ma hiérarchie.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top