Here's my problem:
I want to print a table in template which contains every object with every field
Here's my solution:
views.py
def start(request):
all_rows = Person.objects.all()
all_fields_names = Person._meta.get_fields()
content = { 'all_rows': all_rows,
'all_fields_names': all_fields_names }
return render(request, 'start.html', content)
start.html
<table class="table table-striped table-hover table-responsive">
<thead>
{% for names in all_fields_names %}<th>{{ names.name |title }}</th>{% endfor %}
</thead>
<tbody>
{% for row in all_rows %}
<tr>
<td>{{ row.name }}</td>
<td>{{ row.yabadiba }}</td>
<td>{{ row.value1 }}</td>
<td>{{ row.value2 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
Everything works perfectly. The problem is, when I don't know exactly how many fields is in the class. Second of all, my solution break the DRY rule. I've tried:
getattr(row, names)
and nested loops, with no success.
Is there any simple solution?
Moreover: How to print such view for every class?
What you need is values_list query in your views, it returns tuples when iterated over. Each tuple contains the value from the respective field or expression passed into the values_list():
all_fields_names = Mileage._meta.get_fields()
value_fields = [f.name for f in all_fields_names]
all_rows = Mileage.objects.values_list(*(value_fields)) #pass fields to value_list
Then you can use nested for loop in your templates:
{% for row in all_rows %}
<tr>{% for value in row %}<td>{{ value }}</td>{% endfor %}</tr>
{% endfor %}
Related
This might be a confusing question.
I have three tables in sqllite: 1) Events 2) Delegates 3) EventDelegate
1st one stores all events, 2nd one stores all delegates, 3rd one contains the eventid and delegateid to show that the particular delegate is attending that particular event.
In my event details page i only want to show the delegates whose id are present in the event_delegate table along with that event id. Currently im using this code but not working
views.py
def event_det(request, eid):
data = Event.objects.filter(id=eid) //SELECTING ONLY THE CLICKED EVENT
data2 = Delegate.objects.all() // SELECTING ALL THE DELEGATES FROM DB
data3 = EventDelegate.objects.filter(event_id=eid) //SELECTING RECORDS FROM EVENT_DELEGATE WHERE eventid is eid
return render(request, 'event_details.html', {'event': data, 'delegates': data2, 'selectdelegates': data3})
template
<tbody>
{% for del in delegates %}
{% for sd in selectdelegates %}
{% if del.id == sd.delegate_id %}
<tr>
<td>{{ del.id }}</td>
<td>{{ del.first_name }} {{ del.last_name }}</td>
<td>{{ del.email }}</td>
<td>{{ del.phone }}</td>
<td>{{ del.company }}</td>
<td>{{ del.designation }}</td>
<td>View</td>
</tr>
{% endif %}
{% endfor %}
{% endfor %}
</tbody>
I can share more details if required...
If you have a relationship between event and event delegate like this:
class EventDelegate(models.Model):
event = models.ForeignKey(Event, on_delete=models.DO_NOTHING)
delegate = models.ForignKey(Delegate, on_delete=models.DO_NOTHING)
Then you can try like this:
def event_det(request, eid):
data = Event.objects.get(id=eid) //SELECTING ONLY THE CLICKED EVENT
return render(request, 'event_details.html', {'event': data})
# template
{% for e in event.eventdelegate_set.all %}
<tr>
<td>{{ e.delegate.id }}</td>
<td>{{ e.delegate.first_name }} {{ e.delegate.last_name }}</td>
<td>{{ e.delegate.email }}</td>
<td>{{ e.delegate.phone }}</td>
<td>{{ e.delegate.company }}</td>
<td>{{ e.delegate.designation }}</td>
<td>View</td>
</tr>
{% endfor %}
Alternative solution:
#view
def event_det(request, eid):
data = EventDelegate.objects.filter(id=eid) //SELECTING ONLY THE CLICKED EVENT
return render(request, 'event_details.html', {'event_delegates': data})
# template
{% for e in event_delegates %}
// rest of the code as above example
More information can be found in documentation.
If I understand right, EventDelegate models have ForeignKey to an Event and to a Delegate. So what you want is a queryset of EventDelegate objects that are linked to the event in question.
ed_qs = EventDelegate.objects.filter( event_id = event.id )
(maybe add .order_by( "delegate__lastname") for alpha ordering and .select_related()
pass this to your template, and
<tbody>
{% for ed in ed_qs %}
<tr>
{{ed.delegate.whatever}} ...
Alternatively you might use .annotate in the queryset to copy the desired fields of the linked delegate onto the returned objects. You'd then refer to the annotations, via your chosen annotation names such as {{ed.delegate_firstname}}.My guess is that this would be maximally efficient, if that matters.
I am completely stuck in making index function work in cs50 finance! This function should return in a html page a table with the details of the transactions made online (details are saved in a database). But it's not working: even if there is a transaction in my database, my function doesn't find it, the table is empty.
this is my code:
def index():
"""Show portfolio of stocks"""
rows = db.execute("SELECT symbol, price, shares FROM transactions WHERE id = :user_id", user_id=session["user_id"])
transactions_info = []
total_worth = 0
for transaction_info in rows:
symbol = rows [0]["symbol"]
shares = rows [0]["shares"]
price = lookup(symbol)
worth = shares * price ["price"]
total_worth += worth
transactions_info.append(transaction_info)
return render_template("index.html", rows=rows, transactions_info=transactions_info)
And this is my HTML page:
{% extends "layout.html" %}
{% block title %}
Index
{% endblock %}
{% block main %}
<table class="table table-striped" style="width:100%">
<tr>
<th>Symbol</th>
<th>Company</th>
<th>Shares</th>
<th>Price</th>
<th>TOTAL</th>
</tr>
{% for transaction in transactions %}
<tr>
<td>{{ transaction_info.symbol }}</td>
<td>{{ transaction_info.name }}</td>
<td>{{ transaction_info.shares }}</td>
<td>{{ transaction_info.price }}</td>
<td>{{ transaction_info.worth }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
Thanks for your help!
In index() you are sending a list called transactions_info here
return render_template("index.html", rows=rows, transactions_info=transactions_info)
In the html you are looping over a list called transactions here {% for transaction in transactions %}.
I'm beginner in django and i'm using a read-only db, I just wanna make some selects and show it as a table in my template, but I cant return coulmn by column into my html table, help me,
I'm using a directky raw query
Model.py
from django.db import connection
# Create your models here.
def dictfetchall(cursor):
"Returns all rows from a cursor as a dict"
desc = cursor.description
return [
dict(zip([col[0] for col in desc], row))
for row in cursor.fetchall()
]
def my_custom_sql(self):
with connection.cursor()as cursor:
cursor.execute("""
SELECT EQUIP_ID, LINE_CODE, PLANT_CODE
FROM tbs_rm_mnt_shift_sumr
where SUMR_YMD = '20180405' AND SIDE_CODE = 'T' AND
rownum < 20
""" )
row = dictfetchall(cursor)
return row
view.py
from django.shortcuts import render, redirect, get_object_or_404
from .models import my_custom_sql
# Create your views here.
def show_list(request):
query= my_custom_sql(self='my_custom_sql')
return render(request,'monitoring.html', {'query': query})
monitoring.html
<table border="2" style="solid black">
<tr>
<td>Equip</td>
<td>Line</td>
<td>Plant</td>
{% for instance in query %}
{% for field, value in instance.items %}
<tr>
<td>{{ value }} </td>
</tr>
{% endfor %}
{% endfor %}
</tr>
</table>
browser output:
enter image description here
At the moment you are only outputting one td for each row.
{% for instance in query %}
{% for field, value in instance.items %}
<tr>
<td>{{ value }} </td>
</tr>
{% endfor %}
{% endfor %}
It sounds like should loop inside the tr tag:
{% for instance in query %}
<tr>
{% for field, value in instance.items %}
<td>{{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
However, you can't assume the order of the keys in the dictionary, so you should either access the items by key, or rethink whether you want to use dictfetchall.
{% for instance in query %}
<tr>
<td>{{ instance.EQUIP_ID }} </td>
<td>{{ instance.LINE_ID }} </td>
<td>{{ instance.PLANT_CODE }} </td>
{% endfor %}
</tr>
{% endfor %}
I hope anyone can help me.
I query different tables (with different numbers of columns) in my MySQL db to get a preview of the first 100 rows. I want to display the values in a table.
In views.py I have the following piece of code:
cursor.execute("SELECT column_name FROM information_schema.columns WHERE
table_name = '%s';" %table)
columns = cursor.fetchall()
columns_list = [i[0] for i in columns]
cursor.execute("SELECT * FROM %s LIMIT 100;" %table)
preview = cursor.fetchall()
The code in my html template looks like this:
<table>
<tr>
{% if columns_list %}
{% for column in columns_list %}
<th>{{column}}</th>
{% endfor %}
{% endif %}
</tr>
<tr>
{% if preview %}
{% for row in preview %}
<td>{{ row.0 }}</td>
<td>{{ row.1 }}</td>
<td>{{ row.2 }}</td>
<td>{{ row.3 }}</td>
</tr>
{% endfor %}
{% endif %}
</table>
But this works only if my table has 4 columns.
Is there an easier way to split the tuples and allocate them than using lots of for loops and arrays?
Thanks for your help!
You can use a nested for loop to dynamically generate your table columns:
{% if preview %}
{% for row in preview %}
<tr>
{% for col in row %}
<td>{{ col }}</td>
{% endfor %}
</tr>
{% endfor %}
{% endif %}
I want to display a table showing the values of three fields for each of the units in a table. Some assistance with creating the dictionary from the database and passing objects to the template would be greatly appreciated.
#app.route('/')
def index(row):
unit_count = Units.query.count()
unit = Units.query.filter_by(id=row).first()
rows = [] # Unsure how to define rows from Units db table
return render_template('table_overview.html', title='Overview', rows=rows, unit=unit)
{% for row in rows %}
<tr>
<td>{{ row.unit.idnum }}</a></td>
<td>{{ row.unit.product_code }}</td>
<td bgcolor="{{ row.unit.stat_colour }}">{{ row.unit.unit_status }}</td>
</tr>
{% endfor %}
First off your view function can't receive the row input you specify. If you're trying to show all rows in the table you can do it like this:
views.py:
#app.route('/')
def index():
rows = Units.query.all()
return render_template('table_overview.html',
title='Overview',
rows=rows)
table_overview.html (template)
{% for row in rows %}
<tr>
<td>{{ row.idnum }}</a></td>
<td>{{ row.product_code }}</td>
<td bgcolor="{{ row.stat_colour }}">{{ row.unit_status }}</td>
</tr>
{% endfor %}