In my flask / jinja2 app, I am getting some rows from a database to print in a table. For each row I want to define an identifier for the row from the first item, define the class of the row with the second item and print the rest of the row as table data. I am doing it like this, it works but feels a bit kludgy:
{%- for item in row %}
{% if loop.index==1 %}
<tr id="rec{{item}}"
{% elif loop.index==2 %}
class="{{item}}" >
{% else %}
<td>{{item}}</td>
{% endif %}
{% endfor -%}</tr>
I would like to do something like:
id="rec"+row.pop()
class=row.pop()
then use the variables id and class to define the row and afterwards iterate through what is left of the list. Is this possible in jinja2?
(Using jinja 2.8 as installed on debian 9, but may of course upgrade if that makes things better)
I think you can use slicing in Jinja templates, could you try this, since I can't test it atm:
<tr id="rec{{row[0]}}"
class="{{row[1]}}" >
{% for item in row[2:] %}
<td>{{item}}</td>
{% endfor -%}
</tr>
You could get the first items from the array using their indices and use a slice (e.g. row[2:]) of the array for the for-loop:
<tr id="rec{{row[0]}}" class="{{row[1]}}" >
{%- for item in row[2:] %}
<td>{{item}}</td>
{% endfor -%}</tr>
Related
In my template I have
<p>{% for dict_item in MySQL_Dict %}
{% for key, value in dict_item.items() %}
{{value}}
{% endfor %}
{% endfor %}</p>
Which outputs 43.8934276 -103.3690243 47.052060 -91.639868 How do I keep values i.e. the coordinates together AND have them separated by a comma? Is this possible?
The easiest way is to format it on back-end and pass it the jinja in the way you want. In fact its better to put complex logic on the back-end not the front-end performs better and in jinja's case you don't have to pass in python methods so it's cleaner... other templating frameworks like tornados include all of pythons base functions so you don't have to pass them in like the example below. Another way to do it is to pass the str.join, len, and range method to jinja e.x join=str.join, len=len, range=range then... and I'm guessing MySQL_Dict is a 2d array, hence the double for loop
<p>
{% for dict_item in MySQL_Dict %} // dict_item == [{}, {}, ...]
{% for i in range(len(dict_item)) %} // dict_item[i] == {some object}
{{",".join(dict_item[i]["latitude"], dict_item[i]["longitude"])}}
{% endfor %}
{% endfor %}
</p>
I have a table in SQLite3 and I need to take nearly all the columns in the table and output them to a web page. For other pages I've used flask, but that has always been a case of passing 3 or 4 single value variables into the template.
I'm guessing it's something like passing either the cursor or, more likely, the rows from the cursor.fetchall() call into the template then a for row in rows loop in the template?
It should be:
<table>
{% for item in items %}
<tr>
<td>{{column1}}</td>
<td>{{column2}}</td>
<td>{{column3}}</td>
<td>{{column4}}</td>
</tr>
{% endfor %}
</table>
You need to follow the below:
[HTML]:
<table>
{% for item in items %}
<tr>
<td>{{item[0]}}</td>
<td>{{item[1]}}</td>
<td>{{item[2]}}</td>
<td>{{item[3]}}</td>
</td>
{% endfor %}
[python code]:
cursor = db.execute('SELECT column1,column2,column3,column4 FROM tablename')
items = cursor.fetchall()
return render_template('print_items.html', items=items)
Pass your data as some sort of collection, whether that's something like a dictionary in the official tutorial, or something simpler, like a tuple or list.
Yes, in your template, you'll use a {% for item in collection %} -> {% endfor %} loop to render out all of the data from your database.
Example Python method:
#app.route('/print_items')
def print_items():
cursor = db.execute('SELECT column1,column2,column3,column4 FROM tablename')
return render_template('print_items.html', items=cursor.fetchall())
Example template section:
<table>
{% for item in items %}
<tr>
<td>column1</td>
<td>column2</td>
<td>column3</td>
<td>column4</td>
</td>
{% endfor %}
I'm trying to display table rows with alternating colors. For that, I have two css classes row1 and row2 that I'd like to assign in an alternating pattern to the rows of a table. Ideally, I'd determine if the row is odd or even based on the forloop.counter variable
This is what I'd like the template to do (invalid code, but I think it's self explaning).
{% for norma in normas %}
{% if forloop.counter %2 != 0 %}
<tr class="row1">
{% else %}
<tr class="row2">
{% endif %}
<td>yadda... yadda</td>
.
.
.
{% endfor %}
Is there a way to do this within django template system?
Use cycle - the example shows this exact purpose
Just use in your {%for%} loop :
<tr class="{% cycle 'row1' 'row2' %}>
django templete will cycle through each row. you can add as many items in the cycle.
the followin post explains how to get alternating row colors in Django.
Alternate Row Coloring in Django Template with More Than One Set of Rows
I am writing a template for my first django website.
I am passing a list of dictionaries to the template in a variable. I also need to pass a few other lists which hold boolean flags. (Note: all lists have the same length)
The template looks something like this:
<html>
<head><title>First page</title></head><body>
{% for item in data_tables %}
<table>
<tbody>
<tr><td colspan="15">
{% if level_one_flags[forloop.counter-1] %}
<tr><td>Premier League
{% endif %}
<tr><td>Junior league
<tr><td>Member count
{% if level_two_flags[forloop.counter-1] %}
<tr><td>Ashtano League
{% endif %}
</tbody>
</table>
{% endfor %}
</body>
</html>
I am getting the following error:
Template error
In template /mytemplate.html, error at
line 7 Could not parse the remainder:
'[forloop.counter-1]' from
'level_one_flags[forloop.counter-1]'
I am, not suprised I am getting this error, since I was just trying to see if would work. So far, from the documentation, I have not found out how to obtain the items in a list by index (i.e. other than by enumeration).
Does anyone know how I may access a list by index in a template?
In short, Django doesn't do what you want.
The for loop has a number of useful properties within a loop.
forloop.counter The current iteration of the loop (1-indexed)
forloop.counter0 The current iteration of the loop (0-indexed)
forloop.revcounter The number of iterations from the end of the loop (1-indexed)
forloop.revcounter0 The number of iterations from the end of the loop (0-indexed)
forloop.first True if this is the first time through the loop
forloop.last True if this is the last time through the loop
forloop.parentloop For nested loops, this is the loop "above" the current one
You could probably use forloop.counter0 to get the zero-based indexes you want; unfortunately, the Django template language doesn't support variable array indexes (You can do {{ foo.5 }}, but you can't do {{ foo.{{bar}} }}).
What I usually do is to try and arrange the data in the view to make it easier to present in the template. As an example, for you could create an array in your view composed of dictionaries so that all you have to do is loop through the array and pull exactly what you need out of the individual dictionaries. For really complicated things, I've gone so far as to create a DataRow object that would correctly format the data for a particular row in a table.
You use the dot-operator to index the array, or, really, to do anything.
Technically, when the template system
encounters a dot, it tries the
following lookups, in this order:
* Dictionary lookup
* Attribute lookup
* Method call
* List-index lookup
I don't believe you can do math on the index. You'll have to pass in your array constructed in some other way so that you don't have to do this subtraction.
Try using "slice" to access a list by index
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#slice
Perhaps a better way is to use forloop.last. Of course, this will require that you send to the template the specific level_one_flag and level_two_flag out of the level_one_flags and level_two_flags arrays, but I think this solution keeps a better logical separation between view and template:
<html>
<head><title>First page</title></head><body>
{% for item in data_tables %}
<table>
<tbody>
<tr><td colspan="15">
{% if forloop.last and level_one_flag %}
<tr><td>Premier League
{% endif %}
<tr><td>Junior league
<tr><td>Member count
{% if forloop.last and level_two_flag %}
<tr><td>Ashtano League
{% endif %}
</tbody>
</table>
{% endfor %}
</body>
</html>
I'm developing a Django-based site for fun, and wondered if anyone knows how to solve this problem. I want to display images in a table, like a gallery, inside a template. Does anyone know how to do this? I've tried a multidimensional list, but I am getting nowhere.
I believe question is more CSS related than Django.
Are all your images the same size? If yes, just float all of them and let the bounding div break the images. Your template would looks like something like this (ignore the inline CSS!):
<div style="width:400px">
{% for image in image_list%}
<div style="float:left; width:100px; height:100px;">
{{ image.whatever }}
</div>
{% endfor%}
</div>
This would give you a "table" with 4 columns.
If your images have different widths and heights, I would go with something like display:inline-block, this article explains how it works:
http://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/
Edit If all you want is to convert a list into a table, I guess you can use this template:
{% for image in image_list %}
{% if forloop.first %}
<tr>
{% endif %}
<td>{{ forloop.counter }} - {{ image }}</td>
{% if forloop.last %}
</tr>
{% else %}
{% if forloop.counter|divisibleby:"4" %}
</tr><tr>
{% endif %}
{% endif %}
{% endfor %}
But this code is not tested! I just wrote it :)
Why don't you use a dictionary? Then you could represent points (0,0), (1,1), (0,1) etc with something like this,
mydict = {0: [0, 1, 2],
1: [0, 1, 2],
2: [0, 1, 2]}
where the elements of the list are your image names.
{0: ["image1.jpg", "image2.jpg", "image3.jpg"] .. }
In this case, mydict[0][0] refers to the first element of the first row, and so on.
--
To access a dict in the template (Django Doc), you could use something like,
# (key would be 0, value would be a list [0,1,2,3..]
{% for key, value in mydict.items %}
{% for img in value %}
<img src="{{img}}">
{% endfor %}
{% endfor %}
Do you really need to use table to align your images the way you need? If you need to get something like this http://blog.mozilla.com/webdev/files/2009/02/gallery-view.jpg, please take a look at inline-block CSS property. It is supported by all major browsers including IE6+ (with a little fix).
http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/
Here's a much much simpler way that what others have answered:
The goal is to create a new row after each 4th image displayed. A 1 dimensional list is all you need.
One option would be to close the after each 4th . You can use the forloop.counter or you can use {% cycle '' '' '' '' %} after you create each tag. Note: I'm speculating a bit about your HTML structure. {% cycle '' '' '' '' %} might do just as fine.
Here is what cycle does: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#cycle
If you're using s floated to the left, use the same cycle but add a line break after each 4th .