Reputation: 1359
Let's say my sql table looks like this..
products table
--------------------------------
| id | Model| Manufacturer |
--------------------------------
| 1 | ABC | Samsung |
| 2 | XYZ | LG |
| 3 | ZYX | Sony |
--------------------------------
in django view i fetched all records from this table and passed it to template..
def compare(request):
product_ids = request.GET.get('product_ids')
products = Product.objects.filter(id__in=product_ids)
return render(request, 'compare.html', {'products': products})
as query_set result records comes like one after the other we can say it is following row wise but for this case in template i wanted to create an html table and the result should come like this ..
--------------------------------------------
|id | 1 | 2 | 3 |
|Model | ABC | XYZ | ZYX |
|Manufacturer | Samsung | LG | Sony |
--------------------------------------------
By looking at above example you can see data is rendered as column wise.
so please suggest me a better method in Django by which i can achieve this and also please correct me if i'm wrong as i'm beginner in Django.
Thanks in advance
Upvotes: 4
Views: 5150
Reputation: 796
You can use pandas.DataFrame.transpose()
i.e.,
import pandas as pd
from django_pandas.io import read_frame
df = read_frame(product)
table_html = df.transpose().to_html()
You just pass the table_html
string to the template; no template logic needed here. There are several ways to convert a QuerySet to a DataFrame. Here I'm using the django-pandas package.
Upvotes: 2
Reputation: 6865
Use values_list() and convert your queryset to list
products = list(Product.objects.filter(id__in=product_ids).values_list('id', 'Model', 'Manufacturer'))
# OUTPUT: [(1, 'ABC', 'Samsung'), (2, 'XYZ', 'LG'), (3, 'ZYX', 'Sony')]
Now transpose this 2d matrix using zip
t_products = list(zip(*products))
# OUTPUT: [(1, 2, 3), ('ABC', 'XYZ', 'ZYX'), ('Samsung', 'LG', 'Sony')]
finally you can loop over it in your template
<table>
<tbody>
{% for pl in t_products %}
<tr>
{% for l in pl%}
<td>{{l}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
Upvotes: 6
Reputation: 996
You could use Bootstrap's grid system:
<div class="row">
<div class="col-xs-3">
<p>id</p>
<p>Model</p>
<p>Manufacturer</p>
</div>
{% for product in products %}
<div class="col-xs-3">
<p>{{ product.id }}</p>
<p>{{ product.model }}</p>
<p>{{ product.manufacturer }}</p>
</div>
{% endfor %}
</div>
col-xs-3
means the style will apply from extra-small screen sizes and upwards (i.e. all screens) and 3
means it will split the screen into 12/3 = 4 parts. If you wanted, for example, 6 columns then you'd have to use col-xs-2
.
If you don't want to bring in the overhead of Bootstrap then you could use flex boxes which were brought in for CSS3.
.flexcontainer {
display: flex;
flex-direction: row;
}
Upvotes: 0
Reputation: 4194
You can do it with this;
<table>
<tbody>
<tr>
<th>ID</th>
{% for product in products %}<td>{{ product.id }}</td>{% endfor %}
</tr>
<tr>
<th>Model</th>
{% for product in products %}<td>{{ product.model }}</td>{% endfor %}
</tr>
<tr>
<th>Manufacturer</th>
{% for product in products %}<td>{{ product.manufacturer }}</td>{% endfor %}
</tr>
</tbody>
</table>
Upvotes: 0