كيف يمكنني تقديم بنية شجرة (متكررة) باستخدام قالب جانغو؟

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

  •  09-06-2019
  •  | 
  •  

سؤال

لدي بنية شجرة في الذاكرة وأرغب في عرضها بتنسيق HTML باستخدام قالب Django.

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

سيكون هناك بعض الأشياء root هذا هو Node, ، و children هي قائمة من Nodeس. root سيتم تمريرها في محتوى القالب.

لقد وجدت هذا مناقشة واحدة حول كيفية تحقيق ذلك، لكن الملصق يشير إلى أن هذا قد لا يكون جيدًا في بيئة الإنتاج.

هل يعرف أحد طريقة أفضل؟

هل كانت مفيدة؟

المحلول

أعتقد أن الجواب القانوني هو:"لا".

ما يجب عليك فعله بدلاً من ذلك هو كشف الشيء الموجود بداخلك منظر الكود، لذا فهي مجرد مسألة تكرار على (in|de) الخدوش في القالب.أعتقد أنني سأفعل ذلك عن طريق إلحاق المسافات البادئة والمسافات البادئة إلى القائمة أثناء التكرار عبر الشجرة ثم إرسال قائمة "سجل السفر" إلى القالب.(سيتم إدراج القالب بعد ذلك <li> و </li> من تلك القائمة، إنشاء البنية العودية مع "فهمها".)

أنا أيضًا متأكد تمامًا من أن تضمين ملفات القالب بشكل متكرر يعد أمرًا حقيقيًا خطأ طريقة للقيام بذلك...

نصائح أخرى

استخدام with علامة القالب، يمكنني عمل قائمة شجرة/متكررة.

عينة من الرموز:

القالب الرئيسي:بافتراض أن "all_root_elems" عبارة عن قائمة تضم جذرًا واحدًا أو أكثر من الشجرة

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

يعرض Tree_view_template.html العناصر المتداخلة ul, li والاستخدامات node متغير القالب على النحو التالي:

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

قد يكون هذا أكثر مما تحتاج إليه، ولكن هناك وحدة Django تسمى "mptt" - تقوم بتخزين بنية شجرة هرمية في قاعدة بيانات SQL، وتتضمن قوالب للعرض في كود العرض.قد تتمكن من العثور على شيء مفيد هناك.

إليك الرابط : django-mptt

لقد فات الأوان) كلكم يستخدمون الكثير من الأشياء غير الضرورية مع العلامات، هذه هي الطريقة التي أقوم بها بالاسترداد:

في القالب الرئيسي:

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

ثم في 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 %}

نعم يمكنك أن تفعل ذلك.إنها خدعة صغيرة ، تمرير اسم الملف إلى {٪ تشمل ٪} كمتغير:

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

يحتوي Django على مساعد قالب مدمج لهذا السيناريو بالضبط:

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

واجهت نفس المشكلة وكتبت علامة القالب.أعلم أن هناك علامات أخرى مثل هذه ولكنني كنت بحاجة إلى تعلم كيفية إنشاء علامات مخصصة على أي حال :) أعتقد أن الأمر قد تم بشكل جيد.

اقرأ سلسلة المستندات للحصول على تعليمات الاستخدام.

github.com/skid/Django-recurse

لا أحد يحب الإملاء؟ربما أفتقد شيئًا ما هنا ولكن يبدو أن هذه هي الطريقة الأكثر طبيعية لإعداد القوائم.يؤدي استخدام المفاتيح كإدخالات والقيم كروابط إلى ظهورها في DIV/NAV وتنطلق بعيدًا!

من قاعدتك

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

اتصل بهذا

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

لم تجرب الوضع الافتراضي أو الأمر الذي تم طلبه حتى الآن ربما لديك؟

تصحيح هذا:

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>

على سبيل المثال - النموذج:

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)

واجهت مشكلة مماثلة، لكنني قمت أولاً بتنفيذ الحل باستخدام JavaScript، وبعد ذلك فكرت في كيفية القيام بنفس الشيء في قوالب Django.

لقد استخدمت الأداة المساعدة التسلسلية لتحويل قائمة النماذج إلى json، واستخدمت بيانات json كأساس للتسلسل الهرمي الخاص بي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top