I am trying to render a table using Django-Python. Let us say I have a record of last names starting from A-Z. Now, I want to create a table based on each letter, and put all the people with that first-letter last name on their own table.
EX:
TABLE A Last names
Adams
Anderson
TABLE B Last names
Barnes
Bill
Brandon
TABLE J Last names
Jackson
Johnson
etc…. ## this is the output I want to achieve
HTML:
<legend>Customers</legend>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr>
{% for idx in people %}
<td>{{ idx.0 }}</td>
<td>{{ idx.1 }}</td>
</tr>
{% endfor %}
</table>
views.py
def index(request):
context = {
"people": People.objects.all()
}
return render(request, 'index.html', context)
I can easily render this. However, I am trying to separate everyone based on their last name by creating as many as 26 tables. I want them to all appear in the same html page, but separated by tables accordingly. I don’t know how many letters I have from the database and I am trying to avoid hard-coding a table with A-Z header. This is because in my app, it is possible that out of 26, I only have 5 letters available. For looping in the html using the {% tags %} are very helpful.
I have been trying to create a table inside of a loop in html but I'm getting funny results. Can anyone please help me out?
Thank you very much!
You need the {% regroup %} tag.
{% regroup people by firstname.0 as initials %}
{% for initial in initials %}
<h2>TABLE {{ initial.grouper }} LAST NAMES</h2>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr>
{% for person in initial.list %}
<td>{{ person.firstname }}</td>
<td>{{ person.lastname }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
Note, your view needs to sort the people by lastname for this to work:
context = {
"people": People.objects.all().order_by('lastname')
}
Related
I have table users that contain column username and entries (a one-to-many relationship with table entries). In my HTML file, I want to display the username and the number of entries from the particular user.
It looks like this:
{% for i in users %}
<tr>
<td>{{ i.username }}</td>
<td>{{ i.entries|length }}</td>
</tr>
{% endfor %}
I want to sort the rows from the user who has the biggest number of entries to the least.
I try this but it doesn't work:
{% for i in users|sort(entries|length) %}
How can I achieve this?
You should ideally create your query-set in you view and in your template, you can access it like so
{% for user in users|sort(attribute="length")
<tr>
<td>{{ user.username }}</td>
<td>{{ user.entries|length }}</td>
</tr>
{% endfor %}
Using length attribute on your item, you can do so with sort(attribute='length'). Taken from the Jinja2 sort filter documentation
Just wondering if Sessions can be used to create a quick compare view of two products on my Django app. I'm listing items for sale and would like a user to be able to 'like' multiple items then have a new view to compare the selected products. Any thoughts?
Thanks
Sure, just assign the list products to a session variable.
Then assign the products list to the template, which could look something like that:
<table>
<tr>
<td></td>
{% for product in products %}
<th>{{ product.title }}</th>
{% endfor %}
</tr>
<tr>
<th>Feature 1</th>
{% for product in products %}
<td>{{ product.feature1 }}</td>
{% endfor %}
</tr>
<tr>
<th>Feature 2</th>
{% for product in products %}
<td>{{ product.feature2 }}</td>
{% endfor %}
</tr>
</table>
I except this question to be relatively easy, but since I am new to Django I am struggling.
I got a QuerySet which is given to a template. Basically I want to create a football (soccer) table. But also in general I want to understand the concept.
So for every team in the teams Query set, the data should be filled in the 5 respective columns. At the moment I solved it by adding a for loop into every column. However, I think that it looks ugly and is unefficient. Moreover, I want to edit the id's for the first three loops.
So what I am looking for: A possibility to set the for loop around the div's but without creating the div's in every loop.
Something like:
{%for team in teams %}
<div id="position">team.position</div>
<div id="name">team.name</div>
...
{% endfor %}
In addition to adding something like:
{% if forloop.counter0 == 0|1|2 %}
add id/class to div row
{% endif %}
Is the smartest way here, adding a variable to the class, meaning class={{xyz}} ?
The template looks at the moment like this.
<div class="row">
<div class="col-md-2" id="position">{% for tea in teams %}{{tea.league_position}}</br>{% endfor %}</div>
<div class="col-md-4" id="name">{% for tea in teams %}{{tea.team_name}}</br>{% endfor %}</div>
<div class="col-md-2" id="points">{% for tea in teams %}{{tea.league_points}}</br>{% endfor %}</div>
<div class="col-md-2" id="goals">{% for tea in teams %}{{tea.goals_shot}}</br>{% endfor %}</div>
<div class="col-md-2" id="received">{% for tea in teams %}{{tea.goals_received}}</br>{% endfor %}</div>
</div>
Thank you for your help!!!!!
Simon
You're building a table out of divs. Use a table instead.
<table>
<tr>
<th>Position</th>
<th>Name</th>
<th>Points</th>
<th>Shots</th>
<th>Goals against</th>
</tr>
{% for t in teams %}
<tr>
<td>{{ t.league_position }}</td>
<td>{{ t.team_name }}</td>
<td>{{ t.league_points }}</td>
<td>{{ t.goals_shot }}</td>
<td>{{ t.goals_received }}</td>
</tr>
{% endfor %}
</table>
If you don't want to include the divs then the only way possible would be to do an ajax request to populate the columns separately...
Below is untested (and probably wrong) but it should give an idea of what I mean
$.get('my_get_teams_url', function(data){
for(i = 0; i < data.teams.length; i++)
{
$('#position').append(data.teams[i].position);
$('#name').append(data.teams[i].name);
}
});
I'm working with Flask on building a Bootstrap table out of a list of people taken from a SQLAlchemy database. However, the information I want to put in the table is appearing above it.
Here's the code in question:
<!DOCTYPE html>
{% extends "base.html" %}
{% block page_content %}
<div class="page-header">
<h1>componentes familiares</h1>
<table class="table">
<thead>
<th>name</th>
<th>age</th>
<th>option</th>
</thead>
<tbody>
{% for person in people %}
<tr>{{ person.name }}</tr>
<tr>{{ person.age }}</tr>
<tr>{{ person.option }}</tr>
{% endblock %}
</tbody>
</table>
{% endblock %}
(This is already a slimmed-down version, since I kept taking stuff off to see if it would solve the problem.)
But let's say I have two persons in my database, Alice, and Bob. Alice is 30 and Bob is 40, Alice's option is 1 and Bob's is 2. This is what I get:
The information is there, but it's rendered above the table. And right below it comes the table header and an empty table row.
Links
I found another question about Bootstrap tables in Flask here, but it didn't really solve my problem. My data is being passed to the html page exactly as I want it, I just want to put it in a table.
I also found Flask-Table, an extension to build the table in Python and then using it. It may end up being a solution, but I still don't see what's wrong with my code.
Didn't find anything useful in the Bootstrap docs either.
Any help greatly appreciated!
You're missing a few <tr> and <td> tags:
<table class="table">
<thead>
<tr>
<th>name</th>
<th>age</th>
<th>option</th>
<tr>
</thead>
<tbody>
{% for person in people %}
<tr>
<td>{{ person.name }}</td>
<td>{{ person.age }}</td>
<td>{{ person.option }}</td>
</tr>
{% endfor %}
</tbody>
</table>
You're aiming for a table-row (<tr>) per user, and some table-data (<td>) for each of their attributes. You've also got a {% endblock %} where you should have an {% endfor %}.
I am trying to create HTML tables from data stored in a table. My data is read from a table and converted into a dict of lists, e.g.:
x = {'date':[u'2012-06-28', u'2012-06-29', u'2012-06-30'], 'users': [405, 368, 119]}
My goal is to create an HTML table with the following structure for an arbitrary list length:
<table>
<thead>
<th>Date</th>
<th>Users</th>
</thead>
<tbody>
<tr>
<td>2012-06-28</td>
<td>405</td>
</tr>
<tr>
<td>2012-06-29</td>
<td>368</td>
</tr>
<tr>
<td>2012-06-30</td>
<td>119</td>
</tr>
</tbody>
</table>
I have tried doing this two incorrect ways in my Flask template:
<tbody>
{% for line in x %}
<tr>
<td>{{ x.date|tojson|safe }}</td>
<td>{{ x.users }}</td>
</tr>
{% endfor %}
</tbody>
Which prints the entire list into each column.
And:
{% for date in x.date %}
<tr><td>{{ date|tojson|safe }}</td></tr>
{% endfor %}
{% for users in x.users %}
<tr><td>{{ users }}</td></tr>
{% endfor %}
Which simply prints everything into the first column.
These experiments and many other dead ends lead me to believe that there is no simple way to build the table as I would like given my current data structure.
Given this, I have two questions:
1) How would I go about building the table using my current data structure?
2) What is the standard or ideal way to structure data for this use case?
Thanks in advance.
Like you said, you could either change your data structure, or change your template code. Here is one way to keep the current structure:
{% for row_index in range(x['date']|count) %}
<tr>
<td>{{ x[row_index]['date']|tojson|safe }}</td>
<td>{{ x[row_index]['users'] }}</td>
</tr>
{% endfor %}
Or you could restructure your data in python:
x = zip(x['date'], x['users'])
And then use this template:
{% for row in x %}
<tr>
<td>{{ row[0]|tojson|safe }}</td>
<td>{{ row[1] }}</td>
</tr>
{% endfor %}
You can also structure the data so that the template does not depend on the order of the cells:
from itertools import izip
x = [dict(date=d, user=u) for d, u in izip(x['date'], x['users'])]
Then you can access your data like this:
{% for row in x %}
<tr>
<td>{{ row['date']|tojson|safe }}</td>
<td>{{ row['user'] }}</td>
</tr>
{% endfor %}
You might use Flask-Table or for something more complex even leverage Flask-Admin.
Yeah, you really want to use a list of dictionaries instead of a dictionary of lists, that works out better with Jinja2