简体   繁体   中英

Looping over multiple lists in Django Template

I have a django template that I want to display a bunch of html tables created in my view. I'm passing in a list where each element in the list is an html table. I also want to label the tables but I am having trouble figuring out how to loop over the list of html tables and the list of labels correctly.

In views.py I create the html tables from simple dataframes:

##task_dict is a dictionary where the values are lists of dataframes.
keys = task_dict.keys()
html_dict = dict.fromkeys(keys,[])

for key in keys:
    for df in task_dict[key]:
        temp_html = df.to_html(classes="table table-hover")
        html_dict[key].append('<br>')
        html_dict[key].append(temp_html)

labels = ['New Plan','New Operation','Current Operation']
html_dict['labels'] = labels

return render(request,'InterfaceApp/SchedulerIngestResults.html',html_dict)

My html template currently looks like this:

 <div class="panel panel-body">
    {% for df in key1 %}
      {% for l in labels %}
        <div class="panel-heading">{{ l }}
          <div class="table-responsive">
            {{ df | safe }}
          </div>
        </div>
      {% endfor %}
    {% endfor %}
  </div>

I know this isn't right but I can't figure out how to do it correctly. All I want is for it to look like this:

Table Label1

Table 1


Table Label2

Table 2

Since this is kind of difficult troubleshoot without creating a django app from scratch, I'm going to be doing a lot of thinking out loud.

First, let's look at your template. You have

 <div class="panel panel-body">
    {% for df in key1 %}
      {% for l in labels %}
        <div class="panel-heading">{{ l }}
          <div class="table-responsive">
            {{ df | safe }}
          </div>
        </div>
      {% endfor %}
    {% endfor %}
</div>

Now, let's set key1 and labels to something simple for this. How about ...

key1 = {'df1' : df1TableHTML, 'df2' : df2TableHTML}
labels = ['label1', 'label2']

Now, let's see how you're for-loops will structure the html.

<div class="panel panel-body">

  <div class="panel-heading"> label1
    <div class="table-responsive">
      df1TableHTML
    </div>
  </div>

  <div class="panel-heading"> label2
    <div class="table-responsive">
      df1TableHTML
    </div>
  </div>

  <div class="panel-heading"> label1
    <div class="table-responsive">
      df2TableHTML
    </div>
  </div>

  <div class="panel-heading"> label2
    <div class="table-responsive">
      df2TableHTML
    </div>
  </div>

</div>

I'm sure at this point you can see where your problem is. Since you are using a nested for-loop, you end up with much more output than you originally wanted. To solve this, you want to iterate over key1 and labels simultaneously.

A pythonic way of doing this is by using the zip() command.

>>> a = ['a','b','c']
>>> b = ['A','B','C']
>>> for x in zip(a,b):
...     print x
... 
('a', 'A')
('b', 'B')
('c', 'C')

However, Django doesn't have a zip equivlent for a template tag. This means you'll have to do this "zipping" server side in your views.py. Do something like below.

...
labels = ['New Plan','New Operation','Current Operation']
html_dict['labels_tables'] = zip(label, list_of_tables)

Then in your template, do this.

<div class="panel panel-body">
  {% for lt in label_table %}
    <div class="panel-heading">{{ lt.0 }}
      <div class="table-responsive">
        {{ lt.1 | safe }}
      </div>
    </div>
  {% endfor %}
</div>

Hopefully this answers your question and sorry for the verbose answer. Let me know if this works and I'm happy to give you further help if this isn't what you were looking for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM