string formatting in Html - python

I am creating a template in HTML
{% for product in products %}
<tr>
<td>{{ product.id }}</td>
<td>{{ product.product_name }}</td>
{% for i in quantities %}
{% if forloop.counter == forloop.parentloop.counter %}
<td id="q1">{{ i }}</td>
{% endif %}
{% endfor %}
{% endfor %}
How can I assign a different id to each item in quantities?
Can I use .format just like we do in python?

Like this?
{% for i in quantities %}
<td id="q{{ forloop.counter }}">{{ i }}</td>
{% endfor %}

Related

Django Form as a Table

The following code in the django template language is working but i don't know why. The purpose of this code is to display a form as a table with a number of columns. The first thing that throws me of is that the tag for opening a row is never giving but it is still made.
{% extends 'base.html' %}
{% load render_table from django_tables2 %}
{% block content %}
<form method="get">
{% csrf_token %}
<table>
<tbody>
{% for field in filter.form %}
<td>{{ field.label}}</td>
<td>{{ field }}</td>
{% if forloop.counter|divisibleby:"4"%}
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<input type="submit" value="Search">
</form>
{% render_table table%}
{% endblock %}
This generates a four column table. Is there any way the opening tags can be explicitly declared?And why is this code working?
I have tried to explicitly create the tags for row explicitly but this didn't not create the table correctly.It had an empty row space and a extra row.
{% extends 'base.html' %}
{% load render_table from django_tables2 %}
{% block content %}
<form method="get">
{% csrf_token %}
<table>
<tbody>
{% for field in filter.form %}
{% if forloop.counter|divisibleby:"5"%}
<tr>
{% endif %}
{% if forloop.counter|divisibleby:"5" == False %}
<td>{{ field.label}}</td>
<td>{{ field }}</td>
{% endif %}
{% if forloop.counter|divisibleby:"5"%}
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<input type="submit" value="Buscar">
</form>
{% render_table table%}
{% endblock %}
Why is this working? HTML is pretty lax and browsers can infer what you're trying to do with the context. td before a tr, there should be a row before -> add one
any way the opening tags can be explicitly declared? I believe with a combination of what you have and {% forloop.first %} + {% forloop.last %} this can be done.
Something along the lines of:
<table>
<tbody>
{% for field in filter.form %}
{% if forloop.first %}
<tr>
{% endif %}
<td>{{ field.label}}</td>
<td>{{ field }}</td>
{% if forloop.last %}
<tr>
{% elif forloop.counter|divisibleby:"4"%}
</tr>
<tr>
{% endif %}
{% endfor %}
</tbody>
</table>
Thanks I have put the following code which also works. I think it is now more deliberate. The first if creates the opening tag since the next tag should be a pair generated from the divisible these are in the elif the if contains the last tag which should be a closing tag alone since if it where a divisible pair of tags it would create a extra row.
{% extends 'base.html' %}
{% load render_table from django_tables2 %}
{% block content %}
<form method="get">
{% csrf_token %}
<table>
<tbody>
{% for field in filter.form %}
{% if forloop.first %}
<tr>
{% endif %}
<td>{{ field.label}}</td>
<td>{{ field }}</td>
{% if forloop.last %}
</tr>
{% elif forloop.counter|divisibleby:"4"%}
</tr>
<tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<input type="submit" value="Buscar">
</form>
{% render_table table%}
{% endblock %}

TypeError: 'Class' object not iterable - flask/sqlalchemy/jinja

I'm retrieving data from a database and I want to put it into a table. I'm using SQLAlchemy and an SQLite database.
Here is the code I have in my routes.py:
headings = ('Name', 'Code')
classes = tuple(list(ClassName.query.filter_by(id=current_user.id).all()))
print(classes)
return render_template("view.html", headings=headings, classes=classes)
Here is the code in view.html:
<div class="view-table">
<table>
<tr>
{% for header in headings %}
<th>{{ header }}</th>
{% endfor %}
</tr>
{% for row in classes %}
<tr>
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
</div>
Whenever I run it, I get this error:
TypeError: 'Class' object is not iterable
I was following this tutorial which is why I changed the list into a tuple: https://youtu.be/mCy52I4exTU
I found the answer to this.
In my routes.py, I did this:
classes = Classes.query.filter_by(classAdminID=current_user.id).all()
In my view.html, I did this:
<div class="view-table">
<table>
<tr>
{% for header in headings %}
<th>{{ header }}</th>
{% endfor %}
</tr>
{% for row in classes %}
<tr>
<td>{{ row.Name }}</td>
<td>{{ row.Code }}</td>
</tr>
{% endfor %}
</table>
</div>
I found the solution in this video: https://youtu.be/hbDRTZarMUw

Color coding cells in a table based on the cell value using Jinja templates

I have a simple flask app and need to display a table of values, with the cell backgrounds colour coded based on the cell value according to thresholds. I'm generating the table content as follows:
{% block dashboard_table2 %}
<table>
{% for row in data %}
{% for item in row %}
<td>{{ item }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% endblock %}
I tried wrapping the values in style tags like this in Python but it didn't work:
if int(value) <= 10:
value = '<p style="background-color:Red">' + value + '</p>'
I'm guessing the CSS for the page is overriding the style attribute. I also tried just setting the text color attribute instead of background-color but no dice. Any suggestions on a good way to do this? I'd like to have a concise way to specify threshold values that aren't hard-coded in the templates.
The easiest way would be to put this display logic in your template:
<table>
{% for row in data %}
<tr>
{% for item in row %}
{% if item <= 10 %}
<td class="under-limit">{{ item }}</td>
{% else %}
<td>{{ item }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</table>
Then, in your CSS you can use:
.under-limit { background-color: red; }
<table>
{% for row in row %}
{% if item <= 10 %}
<tr style ="background-color: red">
<td> {{ item }} </td>
</tr>
{% else %}
<tr>
<td> {{ item }} </td>
</tr>
{% endif %}
{% endfor %}
</table>
This works for me.

Print user groups

I would like to print information about all my users and their groups in a template, like this:
{% for user in users %}
<tr>
<td>(there should be enumerate here - 1,2,3,4 etc...)</td>
<td>{{ user.last_name }}</td>
<td>{{ user.first_name }}</td>
<td>
{% for group in user.groups %}
{{ group }}, </td>
{% endfor %}
</tr>
{% endfor %}
but it doesn't work:
'ManyRelatedManager' object is not iterable
I have two additional questions:
1. How can I easily enumerate users, like this:
<tr>
<td>1</td>
<td>Kowalski</td>
<td>John</td>
...
</tr>
<tr>
<td>2</td>
<td>Smith</td>
<td>John</td>
...
</tr>
...
2. How can I print groups like this:
group1, group2, group3
instead
group1, group2, group3,
(last comma is wrong)
Thank you very much.
you should change
{% for group in user.groups.all %}
{{group}}
The following code should do everything you are asking for:
{% for user in users %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ user.last_name }}</td>
<td>{{ user.first_name }}</td>
<td>
{% for group in user.groups.all %}
{{ group }}
{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
Check out the following link from the official docs for more information about builtin forloop variables: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#for

Using keys with spaces

Is there a way to do something like the following in Django templates?
{% for hop in hops%}
<tr>
<td>{{ hop.name }}</td>
<td>{{ hop.mass }}</td>
<td>{{ hop."boil time" }}</td>
</tr>
{% endfor %}
The hop."boil time" doesn't work. The simple solution is rename the key boil_time, but I'm interested in alternatives.
The best way to get at it is to sneak the property name into another variable, like so:
{% for key, value in hop.items %}
{% ifequal key 'boil time' %}
{{ value }}
{% endifequal %}
{% endfor %}
In Django 0.96 (the version used by Google AppEngine) the templating language doesn't support tuple expansion, so it's a bit uglier:
{% for hop in hops %}
<tr>
<td>{{ hop.name }}</td>
<td>{{ hop.mass }}</td>
<td>
{% for item in hop.items %}
{% ifequal item.0 'boil time' %}
{{ item.1 }}
{% endifequal %}
{% endfor %}
</td>
</tr>
{% endfor %}
So, taking your code, we end up with:
{% for hop in hops %}
<tr>
<td>{{ hop.name }}</td>
<td>{{ hop.mass }}</td>
<td>
{% for key, value in hop.items %}
{% ifequal key 'boil time' %}
{{ value }}
{% endifequal %}
{% endfor %}
</td>
</tr>
{% endfor %}
In Django 0.96 (the version on Google AppEnginge), this becomes:
{% for hop in hops %}
<tr>
<td>{{ hop.name }}</td>
<td>{{ hop.mass }}</td>
<td>
{% for item in hop.items %}
{% ifequal item.0 'boil time' %}
{{ item.1 }}
{% endifequal %}
{% endfor %}
</td>
</tr>
{% endfor %}
There's even a wordier way to get at it, using the regroup tag:
{% regroup hop.items by 'boil time' as bt %}
{% for item in bt %}
{% if forloop.first %}
{% for item2 in item.list %}
{% for item3 in item2 %}
{% if not forloop.first %}
{{ item3 }}
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}
You could use a get filter from djangosnippets: http://www.djangosnippets.org/snippets/1412/
(Renaming the key is probably better...)
For django 0.96, which is what the Google Appengine uses for templates, the following works:
{% for hop in recipe.get_hops %}
{% for item in hop.items %}
{% ifequal item.0 'boil time' %}
<p>{{ item.1 }}</p>
{% endifequal %}
{% endfor %}
{% endfor %}
item.0 is the key and item.1 is the value. Link.

Categories

Resources