I have a list:
c = [1,2,3,4,5,6,7,8]
in my template, I want to output this as follows:
<table>
<tr>
<td>1</td>
<td>2</td>
<td>...</td>
</tr>
</table>
<table>
<tr>
<td>5</td>
<td>...</td>
<td>8</td>
</tr>
</table>
What is the best way to do this?
If you'd like to make it more generic, you can also use the built in divisibleby tag
{% for value in c %}
{% if forloop.counter0|divisibleby:cut_off %}
<table>
<tr>
{% endif %}
<td>{{value}}</td>
{% if forloop.counter|divisibleby:cut_off %}
</tr>
</table>
{% endif %}
{% endfor %}
where c is the list and cut_off is the slicing number (e.g. 4 in your question). These variables are supposed to be sent the to the template in your view.
You can use slice template filter:
<table>
<tr>
{% for value in c|slice:":4" %}
<td>{{ value }}</td>
{% endfor %}
</tr>
</table>
<table>
<tr>
{% for value in c|slice:"4:" %}
<td>{{ value }}</td>
{% endfor %}
</tr>
</table>
Assuming c is passed in the template context.
slice basically follows usual python slicing syntax:
>>> c = [1,2,3,4,5,6,7,8]
>>> c[:4]
[1, 2, 3, 4]
>>> c[4:]
[5, 6, 7, 8]
Related
I have a list of dict:
data = [{'2479': {'2022-09-04 to 2022-09-10': 28, '2022-08-28 to 2022-09-03': 27},
'ADMINISTRATION': {'2022-09-04 to 2022-09-10': 8},
'1361': {'2022-09-04 to 2022-09-10': 4, '2022-08-28 to 2022-09-03': 5},
'PERSONAL TIME OFF': {'2022-08-28 to 2022-09-03': 8}}]
# '2479' is the project number
# '2022-09-04 to 2022-09-10' is the date range
# 28 is the total number of hours used for the project for that week
I'm trying to convert it to an html table like this:
So far, this is what I have:
Here's my code:
{% macro render_table_header(label) %}
{% for record in content["weeklyUserReport"] %}
{% for project in record %}
{% for week in record[project] %}
<th class="rotate-45 week1">
<div><span class="date">{{week}}</span></div>
</th>
{% endfor %}
{% endfor %}
{% endfor %}
{% endmacro %}
<table
class="table table-header-rotated table-striped-column hours-container"
id="grid"
>
<thead>
<tr>
<th class="row-header"></th>
{{ render_table_header() }}
</tr>
</thead>
<tbody>
{% for record in content["weeklyUserReport"] %}
{% for project in record %}
{% for week in record[project] %}
<tr>
{% if record[project] == project %}
<td class="project-name"></td>
{% else %}
<td class="project-name">{{ project }}</td>
{% endif %}
<td class="week1">{{ record[project][week] }}</td>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}
</tbody>
</table>
I'd like duplicated projects to be removed and for the hours to line in to their corresponding rows. I have <td class="week2">, <td class="week3">, and <td class="week4"> for the other hours but I'm struggling to find a way to do that.
Any suggestions would be greatly appreciated! Thank you.
I think you were confused about how to properly do loops through the list of dictionaries on the jinja template. I can give a "replica" of what you have done. Try to do something like this on your HTML:
<body>
<table class="table table-header-rotated table-striped-column hours-container" id="grid" style="border: 1px solid black">
<thead>
<tr>
<th style="border: 1px solid black">project name</th>
{% for d in date %}
<th class="row-header" style="border: 1px solid black">{{d}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for record in data %}
{% for project_key, project_value in record.items() %}
<tr>
<td>{{ project_key }}</td>
{% for value in project_value.values() %}
<td class="week1" style="border: 1px solid black">{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
</body>
Here is my controller:
#app.route("/")
def index():
data = [{'2479': {'2022-09-04 to 2022-09-10': 28, '2022-08-28 to 2022-09-03': 27},
'ADMINISTRATION': {'2022-09-04 to 2022-09-10': 8},
'1361': {'2022-09-04 to 2022-09-10': 4, '2022-08-28 to 2022-09-03': 5},
'PERSONAL TIME OFF': {'2022-08-28 to 2022-09-03': 8
}}]
date = ['2022-09-04', '2022-08-28']
return render_template('index.html', date=date, data=data)
Here is the result I got:
I have a long dictionary of data which looks like this,
('Item', 8): Components_data(base_quantity=63.0, items_data={'830927': [1.0, 14.851799999999999], '831103': [0.37170000000000003, 0.6972720300000002]}, price_labor=374.21824212, total=389.76731415)}
The key is a tuple and my values are in a namedtuple, with 3 integers and 1 dictionary where keys are strings and values are integers.
I want to use those values to build an Html table dynamically using jinja:
the result I want need to look like this:
Where the rows of components, Qty and Price unit are generated automatically according to the values of items_data in Componnents_data field.
here is what I have tried so far with jinja :
<table class="table table-bordered">
<thead>
<tr>
<th>Level</th>
<th>Item</th>
<th>Component</th>
<th>Qty</th>
<th>Price Unit</th>
<th>Price Total</th>
<th>Total</th>
</tr>
</thead>
<tbody>
{% for item, components_data in prices.items() %}
<tr>
<td rowspan="3">{{item[1]}}</td>
<td rowspan="3">{{item[0]}}</td>
</tr>
{% for sub_components, sub_comp_dat in components_data.items_data.items()%}
<td>{{sub_components}}</td>
<td>{{ sub_comp_dat[0] }}</td>
<td>{{ sub_comp_dat[1] }}</td>
<td>{{ components_data.price_labor }}</td>
<td>{{ components_data.total }}</td>
</tr>
{% endfor %} {% endfor %}
<tr>
<td colspan="3" id='total-label'>Total</td>
<td colspan="4" id='total-value' text-align='right'>july</td>
</tr>
</tbody>
</table>
And the results looks like this :
I have tried every tip I know but cannot get the expected results, Any Help is welcome.
Thanks
I do not know the jinja syntax, but you can easily achieve your purpose storing a boolean value to check if the total has been already written.
e.g.:
{% for item, components_data in prices.items() %}
<tr>
<td rowspan="3">{{item[1]}}</td>
<td rowspan="3">{{item[0]}}</td>
</tr>
//set the flag to false
isFirstTime = false
{% for sub_components, sub_comp_dat in components_data.items_data.items()%}
<td>{{sub_components}}</td>
<td>{{ sub_comp_dat[0] }}</td>
<td>{{ sub_comp_dat[1] }}</td>
//show the price only the first time
if( isFortTime)
{
isFistTime = true;
<td rowspan="3">{{ components_data.price_labor }}</td>
<td rowspan="3">{{ components_data.total }}</td>
}
</tr>
{% endfor %}
{% endfor %}
Again this is not the correct syntax but you can achieve this with no problem.
Documentation:
Assign a variable in the template
If Statement
Thanks again #Alessandro.Vegna answer for the intuition of using if else statement.
It can be achieved according to this answer by using namespaces: in jinja 2.0
here is the answer :
<tbody>
{% for item, components_data in prices.items() %}
<tr>
<td rowspan="3">{{item[1]}}</td>
<td rowspan="3">{{item[0]}}</td>
</tr>
{% set time = namespace(first=False) %}
{% for sub_components, sub_comp_dat in components_data.items_data.items() %}
<tr>
<td>{{sub_components}}</td>
<td>{{ sub_comp_dat[0] }}</td>
<td>{{ sub_comp_dat[1] }}</td>
{% if not time.first %}
{% set time.first = True %}
<td rowspan="3">{{ components_data.price_labor }}</td>
<td rowspan="3">{{ components_data.total }}</td>
{% endif %}
</tr>
{% endfor %} {% endfor %}
<tr>
<td colspan="3" id='total-label'>Total</td>
<td colspan="4" id='total-value' text-align='right'>july</td>
</tr>
</tbody>
I'm trying to get my display my list(s) into a html table but it's printing the whole list instead of each variable inside it. I'm using jinja2 templates.
<table>
<tr>
<th>Date:</th>
<th>Scheduled:</th>
</tr>
{% for day in working_days %}
<tr>
<td>{{working_days}}</td>
</tr>
{% endfor %}
</table>
Right now it's just displaying the whole list 7 times instead of each variable from the list in a seperate td.
['maandag 12 maart', 'dinsdag 13 maart', 'woensdag 14 maart',
'donderdag 15 maart', 'vrijdag 16 maart', 'zaterdag 17 maart', 'zondag
18 maart']
This would solve the problem:
{% for day in working_days %}
<tr>
<td>{{day}}</td> {# <- not working_days #}
</tr>
{% endfor %}
<table>
<tr>
<th>Date:</th>
<th>Scheduled:</th>
</tr>
{% for day in working_days %}
<tr>
<td>{{ day }}</td>
</tr>
{% endfor %}
replace {{day}} with {{working_days}}
Hope , It'll Help you.
You just need more for
{% for day in working_days%}
{% for d in day %}
<tr><td>{{d}</td></tr>
{% endfor %}
{% endfor %}
I have a dictionary where value are in list
{
'Fees': ['88000', '88000'],
'ROll Number': ['I0', 'I1'],
'Mark': [10, 10]
}
So I am trying to insert this data in table, SO my Django template are
<table>
<thead>
<tr>
{% for k, v in loan_bank_info.items %}
<th>{{ k }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
<tr>
{% for k, value in loan_bank_info.items %}
{% for v in value %}
<td>{{ v }}</td>
{% endfor %}
{% endfor %}
</tr>
</tbody>
</table>
but in table value are printing as follow,
Fees ROll Number Mark
88000 88000 I0 I1 10 10
But what I want is -
Fees ROll Number Mark
88000 I0 10
88000 I1 10
how to iterate over list value in Django template
You can just iterate over the list. Something like below
<tr>
{% for k, value in loan_bank_info.items %}
{% for v in value %}
{% for i in v %}
<td>{{ i }}</td>
{% endfor %}
{% endfor %}
{% endfor %}
</tr>
If I have the following lists:
headers = ['Name', 'Age']
rows = [['Johnny', 30], ['Zack', 20]]
I can easily make a table via Jinja2 (https://jsfiddle.net/equbh9du/1/):
<table class="table table-bordered table-hover">
<thead>
<tr>
{% for h in headers %}
<td>{{ h }}</td>
{% endfor %
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
{% for item in row %}
<td>{{ item }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
I'm noticing it's much easier (and more organized) to return my data as a dictionary:
d = {'Name': ['Johnny', 'Zack'], 'Age': [30, 20]}
Is there an easy way to build the table I built above using this dict. I imagine I need to finish the iteration down each column before continuing to the next column (in the example above I finish the iteration across each row before continuing to the next row).
This is the code I have so far but I'm getting a messed up table (https://jsfiddle.net/j164fqy9/1/):
<table class="table table-bordered table-hover">
<thead>
<tr>
{% for h in d %}
<td>{{ h }}</td>
{% endfor %
</tr>
</thead>
<tbody>
{% for h, col_values in d.items() %}
{% for item in col_values %}
<tr>
<td>{{ item }}</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
EDIT: If HTML standard prevents iterating down columns first, then I need to construct the headers and rows from d. Is below the best way to do this?
headers = [h for h in d]
rows = [[l[i] for h, l in d.items()] for i in range(len(d['Name']))]
If you allways have the same number of items in col_values this should work fine :
{% for i in range(d['Name']|count) %}
<tr>
{% for k in d %}
<td>{{ d[k][i] }}</td>
{% endfor %}
</tr>
{% endfor %}