Dynamic number of columns in Django template - python

I have recently tried to solve the challenge of handling a dynamic number of columns in my Django template (essentially working through a list containing lists that isnt standerdized).
I pass two things to my view:
test_array: an array that looks something like the following [[1,2,3],[1,2,3],[1,2,3]]
numbers: in this case 3 (indicating the number of attributes in the sub lists
I thought to solve this as follows:
<tbody>
{% for t in test_array %}
<tr>
{% for x in numbers %}
<td>{{ t.x }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
But the above returns no output. When I reference t.1, t.2 etc hardcoded this returns output.
As such, what is the best way to handle a dynamic number of columns in Django? Or, is there a more elegant way to solve the above?

Passing the length of the sublists to the the template isn't necessary.
As the list elements are also lists the inner loop could simply be reduced to this:
{% for x in t %}
<td>{{ x }}</td>
{% endfor %}

Related

Check for a list the elements of which all contain only whitespaces in HTML

I'm building an app in Flask. I'm extracting a variable items (which is a list) and displaying each of its elements in a separate cell.
<tr>
<th>Some heading</th>
{% for item in items %}
<td>{{ item }}</td>
{% endfor %}
</tr>
However, some items lists only contain elements consisting of whitespaces only, for example:
items = [' ', ' ', ' ', ' ']
I want to check that this is NOT the case and create a table row only if at least one element of items contains more than whitespaces. {% if items %} doesn't help because the list has elements. Is there any other way? I don't know JavaScript, but I would be glad to look into that too if there is a way.
With python you can check it with:
if all(map(lambds s: s.strip(),items)):
With JS
if (items.every((item) => item.trim()))
Sorry, found a way out through introducing an items_check in the app file. Basically, I joined the elements into a string and checked it for containing only whitespace. Now {% if items_check %} works :)
#armgar
You need to modify the code and place if condition outside the row of table so that row will only get created when the item in the list is not a whitespace.
I tried this and it's working for me.
<table>
<tr>
<th>Some heading</th>
</tr>
{% for item in items %}
{% if item %}
<tr>
<td>{{item | trim }}</td>
</tr>
{% endif %}
{% endfor %}
</table>

How to build an HTML table using a for loop in Flask?

I am trying to create a table on a webpage using python and flask. I have two lists, testing_sketches and split_reconstructions.
testing_sketches: It is a list of size 14, containing 14 image addresses.
split_reconstructions: It is a list of lists containing 14 lists of length 20. Basically, there are 20 image addresses corresponding to each of the 14 images in the previous list. This means it includes 20 image addresses for each image address in testing_sketches.
I am trying to iteratively take an image from testing_sketches and display its 20 images in split_reconstructions on its right. Something like the following:
And I have tried to implement it using the following code:
<body>
<h2 style="margin-left: 1.5%;">Iterative Reconstructions</h2>
{% for i in range(len(testing_sketches)) %}
<br>
<br>
<h3 style="margin-left: 10%;">{{ i+1 }}.</h3>
<center><table border="1">
<COLGROUP>
<COL width="100"><COL width="100">
<THEAD>
<tr>
<td><center><b>Image<b></center><img src={{ testing_sketches[i] }} alt="Sorry, No Display!" border="0"/></td>
{% for j in range(20) %}
<td><center><b>Reconstruction-{{ j }}<b></center><img src={{ split_reconstructions[i][j] }} alt="Sorry, No Display!" border="0"/></td>
{% endfor %}
</tr>
</table></center>
{% endfor %}
</body>
But this results in a blank result, no alternate display, no error, just an empty result. I have tried to check the length of the lists that I am passing on, and all of them are non-empty and have correct image addresses of the form: static/test_reconstructions/images/image_04666_img.png (an example of one of the addresses)
I pass the lists and the functions used in the app.py file as follows:
#app.route('/')
def home():
return render_template('iterative_reconst.html', testing_sketchs=testing_sketchs, split_reconstructions=split_reconstructions,
len=len, range=range)
If I understood you correctly, you want a table for each entry in the first list. This table shall have the number of columns corresponding to the entry in the respective second list, headed by the entry in the first list.
For this jinja2 provides the filter length and loop indices. Your code would look something like this.
{% for sketch in testing_sketches %}
<table>
<thead>
<th>Image</th>
{% for i in range(split_reconstructions[loop.index0] | count) %}
<th>Reconstruction-{{i+1}}</th>
{% endfor %}
</thead>
<body>
<tr>
<td>{{ sketch }}</td>
{% for addr in split_reconstructions[loop.index0] %}
<td>{{ addr }}</td>
{% endfor %}
</tr>
</tbody>
</table>
{% endfor %}

How to do this in Jinja2?

Hello I am using jinja2 and I have a list of dictionaries that I am passing to jinja template.
{%for dict in list_of_dicts%}
<tr>
{%for key in my_dict.keys()%}
<td> {{my_dict.key}}</td> // Here i want to get value in my_dict with that particular key.
{%endfor%}
</tr>
{%endfor %}
How do I achieve this?
By using just one variable in your for-loop, you just get the value and not the key name. You can use the alternative key, value syntax (as documented here) in a for loop to get the keys in a separate variable, like this:
{% for key, value in my_dict.iteritems() %}
<td>{{ key }}</td>
{% endfor %}

Display of dictionary in django

My List
book_details = [
{'author':'abc', 'book_name':'xyz', 's_no':1},
{'author':'efg', 'book_name':'ijk', 's_no':2}
]
My code:
{% for dict in details %}
<tr>
{% for key, value in dict.items %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
Output :
Author Book_name S_no
Desired output:
S_no Book_name Author
I'm new to django , please guide.
Right now you are iterating through each key-value pair in the dictionary, so your code is outputting dictionary values in the order in which they are stored in the dictionary, which happens to be:
Author Book_name S_no
So, you have two options.
Change the order in which these attributes are stored in the dictionary. If you change the structure of your dictionaries from {'author': 'abc', 'book_name':'xyz','s_no':1} to {'s_no':1, 'book_name':'xyz', 'author': 'abc'}, iterating over the key-value pairs will return these attributes in the desired order. However, this is not a very flexible solution, so I would suggest the second option.
Change the way you output dictionary values. Instead of iterating through all the key-value pairs in whatever order they happen to be in, you can explicitly define the order in which you want to output dictionary values by changing this:
{% for key,value in dict.items %}
<td>{{value}}</td>
{% endfor %}
to this:
{% for key in ['S_no', 'Book_name', 'Author'] %}
<td>{{dict[key]}}</td>
{% end for %}
This solution has the added benefit of being quite easy to modify if, later on, you decide you want to output these values in another order.
{% for dict in details %}
<tr>
<td>{{dict.s_no}}</td>
<td>{{dict.book_name}}</td>
<td>{{dict.author}}</td>
</tr>
{% endfor%}

Indexing a QuerySet array in django templates

I'm trying to access a queryset array that I passed from the views in the templates. I want to index each entry using a numeric iterator. I'm using a django snippet to get the range of customers. Here is what I have done so far:
{% for cust in customer_comments %}
{% for i in cust|length|get_range %}
<tr>
<td>{{cust.i.customer_id}}</td>
<td>{{cust.i.feedback_detail}}</td>
</tr>
{% endfor %}
{% endfor %}
When I iterate using cust.i.customer_id it displays nothing. But when I use cust.0.customer_id or cust.1.customer_id, it displays what I want it to. Kindly help why i is not working.
Btw this is how I initialized the customer_comments object in views.
customer_comments = []
for i in all_features:
if OpenFeedback.objects.filter(feature_id = i.feature_id).exists():
feedback_obj = OpenFeedback.objects.filter(feature_id = i.feature_id)
customer_comments.append(feedback_obj)
You don't iterate like that in Python or in Django templates: you iterate through the list itself.
{% for customer in cust %}
<tr>
<td>{{customer.customer_id}}</td>
<td>{{customer.feedback_detail}}</td>
</tr>
{% endfor %}

Categories

Resources