Come posso eseguire il rendering di una struttura ad albero (ricorsiva) utilizzando un django modello?

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

  •  09-06-2019
  •  | 
  •  

Domanda

Ho una struttura ad albero in memoria che vorrei rendere in HTML utilizzando un Django modello.

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

Ci sarà qualche oggetto root che è un Node, e children è un elenco di Nodes. root sarà passato il contenuto del modello.

Ho trovato questo una discussione di come questo potrebbe essere raggiunto, ma il poster suggerisce che questo potrebbe non essere buono in un ambiente di produzione.

Qualcuno sa di un modo migliore?

È stato utile?

Soluzione

Penso che la risposta canonica è:"Non".

Quello che probabilmente si dovrebbe fare è invece svelare la cosa nel vostro vista il codice, quindi è solo una questione di iterare su (in|de)ammaccature nel modello.Penso che mi piacerebbe farlo aggiungendo rientri e dedents di una lista, mentre recursing attraverso l'albero e quindi l'invio del "diario di viaggio" per il modello.(il modello sarebbe quindi inserire <li> e </li> da tale elenco, creare la struttura ricorsiva con "comprensione" di essa).

Sono anche abbastanza sicuro, in modo ricorsivo, compresi i file di modello è davvero un sbagliato un modo per farlo...

Altri suggerimenti

Utilizzando with tag modello, ho potuto fare l'albero/ricorsiva elenco.

Codice di esempio:

modello principale:supponendo 'all_root_elems' è un elenco di uno o più radici degli alberi

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

tree_view_template.html rende nidificata ul, li e usa node modello variabile, come di seguito:

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

questo potrebbe essere il modo più del necessario, ma c'è un django modulo chiamato 'mptt' - si memorizza una struttura gerarchica ad albero in un database sql, e include modelli per la visualizzazione nella vista codice.si potrebbe essere in grado di trovare qualcosa di utile qui.

ecco il link : django-mptt

Sto troppo tardi) Tutti usi così tanto inutili con tag, questo è come faccio io recuesive:

nel modello principale:

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

quindi 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 %}

Sì, si può fare.E 'un po' di trucco, passando il nome del file {% sono %} come una variabile:

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

Django è dotato di un modello di supporto per questo scenario:

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

Ho avuto lo stesso problema e ho scritto un tag del modello.So che ci sono altri tag come questo là fuori, ma ho bisogno di imparare a fare i tag personalizzati in ogni caso :) penso che è venuto fuori abbastanza bene.

Leggere le docstring per le istruzioni d'uso.

github.com/skid/django-recurse

Nessuno come dicts ?Forse mi manca qualcosa qui, ma sembrerebbe il modo più naturale per menu di impostazione.Utilizzo dei tasti di voci ed i valori di link e pop in un DIV/NAV e si va via !

Dalla vostra base

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

chiamare questo

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

Si non ho provato il default o l'ordinato ancora forse avete ?

correggere questo:

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>

per esempio - modello:

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)

Ho avuto un problema simile, però ho avuto per la prima volta implementato la soluzione utilizzando JavaScript, e solo in seguito considerato come avrei fatto la stessa cosa in modelli di django.

Ho usato il serializzatore utilità per trasformare un elenco di modelli in json, e utilizzato i dati json come base per il mio gerarchia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top