使用动态 id 在 django 中折叠列表组

Collapse list group in django using dynamic id

我正在尝试为 bootstrap 崩溃使用动态 ID。崩溃正在工作,但它没有按预期工作。每个标题里面有多个项目,但是当我点击标题时只显示一个项目。这是我的 index.html

<div class="row">
        <div class="col-md-offset-1 col-md-10">
            <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
            <div class="panel panel-default">
              {% for subject in subjects %}
                 <div class="panel-heading" role="tab">
                 <h4 class="panel-title">
                  <a role="button" data-toggle="collapse" data-parent="#accordion" href="#c{{forloop.counter}}" 
                           aria-expanded="false" aria-controls="c{{ forloop.counter}}">
                    {{ subject }}</a></h4>
                 </div>
              {% for practical in practicals %}
                {% if practical.subject == subject %}
                <div id="c{{forloop.counter}}" class="panel-collapse collapse in" role="tabpanel"">
                  <div class="list-group">
                    <a href="{% url 'practicals:detail' practical.id %}">{{ practical }}</a>
                   </div>
                </div>
                 {% endif %}
              {% endfor %}
            {% endfor %}
          </div>
          </div>
        </div>
    </div>

我已经将 link 添加到 js

我的model.py是:

class Subject(models.Model):
    subName = models.CharField(max_length=100)

    def __str__(self):
        return self.subName

class Practical(models.Model):
    title = models.CharField(max_length=500)
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

我试过用subject_id代替forloop.counter,但还是一样的问题。有人可以帮助我吗?

在介绍主要解决方案之前,我想指出您使用的两个 forloop.counter 是两个不同 forloop 的计数器。您用 href="#c{{forloop.counter}}" 定义的顶部的锚标签正在使用 % for subject in subjects %}.

的 forloop 计数器

但是我假设您要显示的 div(使用 id="c{{forloop.counter}}" 定义的 {% for practical in practicals %} 使用 forloop 计数器。

这将导致数字关闭。

现在,真正的问题在于您 html 的结构。也就是说……当您单击锚标签时,您只显示一个元素。它针对的 id 是一个唯一的 id,它对一个元素是唯一的。因此,只会显示该元素。您可以采取两种选择...

  1. 将元素列表 div 包装在另一个 div 中。如果你这样做,你将不得不以包装器 div 而不是元素为目标。

例如

{% for subject in subjects %}
<div class="panel-heading">
    <a role="button" data-toggle="collapse" data-parent="#accordion" href="#list__practical" 
                       aria-expanded="false" aria-controls="list__practical">
                       {{ subject }}</a>
<div>
<div id="list__practical">
    {% for practical in practicals %}
    {# Your element html here #}
    {% endfor %}
</div>
{% endfor %}

关键是包装实用 forloop 的 id 和对它的引用而不是动态 id。

  1. 使用 类 而不是 ids

例如

{% for subject in subjects %}
<div class="panel-heading">
    <a role="button" data-toggle="collapse" data-parent="#accordion" href=".list-element" 
                       aria-expanded="false" aria-controls="???">
                       {{ subject }}</a>
<div>
{% for practical in practicals %}
    <div class="list-element panel-collapse collapse in" role="tabpanel"">
        <div class="list-group">
            <a href="{% url 'practicals:detail' practical.id %}">{{ practical }}</a>
        </div>
    </div>
{% endfor %}
{% endfor %}

请注意,我之前从未使用过 aria-* 东西,所以我不确定更改 ID 或 类 会如何影响它。