Creating an HTML table with database values in Flask - python

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 %}

Related

can't make index function work in cs50 finance

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 %}.

Templating a directly raw query in a html table

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 %}

How to list tuples of variant lengths into tables in Django?

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 %}

Django - template containing model's 'table'

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 %}

Cannot get HTML to display SQLite3 data with python & flask

I'm having an issue getting an HTML page to display my SQLite3 data using Python & Flask. I found a question on here and used the same code, plus different variations to no success. There are no error messages and the HTML page loads, however there is no data present. This is the code I am using to get the data;
#app.route("/viewpackages", methods=['GET'])
def viewpackages():
con = sqlite3.connect('utpg.db')
db = con.cursor()
user_id = session.get('id')
getpackages = db.execute("SELECT pck_id, client_id, date, price, privatelesson,"
"shortgamelesson, playinglesson, notes FROM packages WHERE client_id = ?;", (user_id, ))
return render_template("view_packages.html", items=getpackages.fetchall())
this is the code I attempting to use to display the data;
<table>
{% for item in items %}
<tr>
<td>{{column1}}</td>
<td>{{column2}}</td>
<td>{{column3}}</td>
<td>{{column4}}</td>
<td>{{column5}}</td>
<td>{{column6}}</td>
<td>{{column7}}</td>
<td>{{column8}}</td>
</tr>
{% endfor %}
</table>
I tried changing 'column' to the actual db column name, with the same issue. I tried calling SELECT * instead of each individual column, same issue. If I run this code in python;
con = sqlite3.connect('utpg.db')
db = con.cursor()
user_id = session.get('id')
getpackages = db.execute("SELECT pck_id, client_id, date, price, privatelesson, shortgamelesson, playinglesson, notes FROM packages WHERE client_id = ?;", (user_id, ))
packages = getpackages.fetchall()
for row in packages:
print(row)
It returns the desired results. So I am thinking there is an issue with the HTML somewhere but I cannot figure it out.
Please try the following code and let me know if it works for you:
<table>
{% for item in items %}
<tr>
<td>{{ item[0] }}</td>
<td>{{ item[1] }}</td>
<td>{{ item[2] }}</td>
<td>{{ item[3] }}</td>
<td>{{ item[4] }}</td>
<td>{{ item[5] }}</td>
<td>{{ item[6] }}</td>
<td>{{ item[7] }}</td>
</tr>
{% endfor %}
</table>
Test with the following code:
app.py
from flask import Flask, render_template
import sqlite3
app = Flask(__name__)
app.secret_key = 'development key'
#app.route('/users')
def get_users():
con = sqlite3.connect('mydb.db')
db = con.cursor()
db.execute('insert into user values ("Aaa", "AAA")')
db.execute('insert into user values ("Bbb", "BBB")')
res = db.execute('select * from user')
return render_template('users.html', users=res.fetchall())
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
templates/users.html
<html !DOCTYPE>
<head>
<title>SQLite</title>
</head>
<body>
<table>
{% for user in users %}
<tr>
<td>{{ user[0] }}</td>
<td>{{ user[1] }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
Here is what I had to do.. For anyone else having this issue, I'm not sure why but Jinja did not want to let me access by index so I did..
#app.route("/viewpackages", methods=['GET'])
def viewpackages():
con = sqlite3.connect('utpg.db')
con.row_factory = sqlite3.Row
db = con.cursor()
user_id = session.get('id')
getpackages = db.execute("SELECT pck_id, client_id, date, price, privatelesson,"
"shortgamelesson, playinglesson, notes FROM packages WHERE client_id = ?;", (user_id, ))
return render_template("view_packages.html", items=getpackages.fetchall())
and change the HTML to..
<table>
{% for col in items %}
<tr>
<td>{{ col['pck_id'] }}</td>
<td>{{ col['client_id'] }}</td>
<td>{{ col['date'] }}</td>
<td>{{ col['price'] }}</td>
<td>{{ col['privatelesson'] }}</td>
<td>{{ col['shortgamelesson'] }}</td>
<td>{{ col['playinglesson'] }}</td>
<td>{{ col['notes'] }}</td>
</tr>
{% endfor %}
</table>
All working now, thank for pointing me in the right direction!

Categories