For loops in HTML Tables (for var in var) - python

I am trying to print some database values onto an HTML page.
The html code is run through a for loop that counts the amount of description values.
However it prints the entire database for each entry of Debit , Credit and Account Number.
I'm pretty sure the problem is inside the for loop structure , please assist.
Home.html:
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
{% extends "main/base.html"%}
{% block content%}
<h1> Kyle Database </h1>
<h2>Trial Balance</h2>
<br>
<br>
<table>
<th>Account</th>
<th>Description</th>
<th>Debit</th>
<th>Credit</th>
{% for xAlls in xAll %}
<tr>
<td>{{ accountNo }}</td>
<td>{{ description }}</td>
<td>{{ debit }}</td>
<td>{{ credit }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
Views.py:
def home(request):
return render(request , 'main/home.html')
def Kyletrb(request):
desc = "SELECT Description FROM [Kyle].[dbo].[_btblCbStatement] WHERE Account <> ''"
cursor = cnxn.cursor();
cursor.execute(desc);
description = [tup[0] for tup in cursor.fetchall()]
accNo = "SELECT Account FROM [Kyle].[dbo].[_btblCbStatement] WHERE Account <> ''"
cursor.execute(accNo);
accountNo = [tup[0] for tup in cursor.fetchall()]
deb = "SELECT Debit FROM [Kyle].[dbo].[_btblCbStatement] WHERE Account <> ''"
cursor.execute(deb);
debit = [tup[0] for tup in cursor.fetchall()]
cred = "SELECT Credit FROM [Kyle].[dbo].[_btblCbStatement] WHERE Account <> ''"
cursor.execute(cred);
credit = [tup[0] for tup in cursor.fetchall()]
all = "SELECT Description, Account ,Credit,Debit FROM [Kyle].[dbo].[_btblCbStatement] WHERE Account <> ''"
cursor.execute(all);
xAll = [tup[0] for tup in cursor.fetchall()]
return render(request , 'main/Kyletrb.html' , {"description":description , "accountNo":accountNo , "debit":debit , "credit":credit , "xAll":xAll})
Output :

First of all, you can make a simple query for all data at once ( as you did in the last fetch ).
I would make a list of dicts like this:
def Kyletrb(request):
all = "SELECT Description, Account ,Credit,Debit FROM [Kyle].[dbo].[_btblCbStatement] WHERE Account <> ''"
cursor.execute(all);
xAll = cursor.fetchall()
cursor.close()
xAll_l = []
for row in xAll:
rdict = {}
rdict["Description"] = row[0]
rdict["Account"] = row[1]
rdict["Credit"] = row[2]
rdict["Debit"] = row[3]
xAll_l.append(rdict)
return render(request , 'main/Kyletrb.html' , {"xAlls":xAll_l})
After that you can make a for loop in template:
<table>
<th>Account</th>
<th>Description</th>
<th>Debit</th>
<th>Credit</th>
{% for xAll in xAlls %}
<tr>
<td>{{ xAll.Description }}</td>
<td>{{ xAll.Account }}</td>
<td>{{ xAll.Debit }}</td>
<td>{{ xAll.Credit }}</td>
</tr>
{% endfor %}
</table>

Try this code
{% for description in description %}
<tr>
<td>{{ description.accountNo }}</td>
<td>{{ description.description }}</td>
<td>{{ description.debit }}</td>
<td>{{ description.credit }}</td>
</tr>
{% endfor %}

You are using the same variable name in your for loop twice.
Normally it would be
for(description in descriptions)
Notice the plurality difference.

You can replace your for loop with the following code. and I hope it will work.
{% for desc in description %}
<tr>
<td>{{ desc.accountNo }}</td>
<td>{{ desc.description }}</td>
<td>{{ desc.debit }}</td>
<td>{{ desc.credit }}</td>
</tr>
{% endfor %}
and make sure that you have same objects of models given in your HTML template

Please try as below.
{% for description in descriptions %}
<tr>
<td>{{ description.accountNo }}</td>
<td>{{ description.description }}</td>
<td>{{ description.debit }}</td>
<td>{{ description.credit }}</td>
</tr>
{% endfor %}

I have figured out the formatting problem .
Instead of using a table, I have used 'div' tags for each column
.html :
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
{% extends "main/base.html"%}
{% block content%}
<h1>Kyle Database Trial Balance</h1>
<br>
<div class="container">
<div class="row mb-0">
<div class="col">
<h3>Account</h3>
{% for accountNo in accountNo %}
<p style="font-size:10px">{{ accountNo }}</p>
{% endfor %}
</div>
<div class="col-4">
<h3>Description</h3>
{% for description in description %}
<p style="font-size:10px">{{ description }}</p>
{% endfor %}
</div>
<div class="col">
<h3>Debit</h3>
{% for debit in debit %}
<p style="font-size:10px">{{ debit }}</p>
{% endfor %}
</div>
<div class="col">
<h3>Credit</h3>
{% for credit in credit %}
<p style="font-size:10px">{{ credit }}</p>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
Output :

Related

How to show in Django queryset dict-key and -values seperately in template?

I have the this output in the browser from HTML template:
{'coin__name': 'Bitcoin', 'total': Decimal('1498824')}
{'coin__name': 'Ripple', 'total': Decimal('335227')}
How can I show in an html template separately the key and the value(without saying Decimal)?
Desired outcome:
Bitcoin, 1498824
Ripple , 335227
I provide the query and the html template below:
views.py:
test = filtered_transaction_query_by_user.values('coin__name').annotate( total = (Sum('trade_price' ) * Sum('number_of_coins'))).order_by('-total')
template.html
<table class="table table-striped">
<tr>
<th>Current dict pair</th>
<th>Just the name of the crypto</th>
<th>Just the price of the crypto</th>
</tr>
{% for item in test %}
<tr>
<td>{{ item }}</td>
<td>{{ }}</td>
<td>{{ }}</td>
</tr>
{% endfor %}
Update template with below code:
{{ test }} <!-- test is list of dictonaries -->
<br>
{% for item in test %} <!-- Loop to get each item(sub dictonary) from list-->
<br>
{% for key,value in item.items %} <!-- Getting key values pairs from each sub dictonary item -->
{% if forloop.last %} <!-- Checking if last iteration of loop just to add "::" after each value -->
{{ value }} <!-- only displying values not keys from each sub dictionary -->
{%else%}
{{value }} ,
{% endif %}
{% endfor %}
{% endfor %}
Refer to this answer for removing decimal from result.
Django: remove Decimal prefix from queryset annotated field, when requesting values
Try fetching both the key and the value from the dictionary in the loop:
{% for key, value in test.items %}
<tr>
<td>{{ key }}</td>
<td>{{ value }}</td>
</tr>
{% endfor %}
If you want to format Decimal value see docs

Can't output data in page

i have 2 tables in DB wallet(id,name) and balance(id,wallet_id)
i need table consisting of 2 cells (post,date)
where will all wallets in first cell and them balance in second
{% for wallets1 in wallets %}
<tr>
{% for balance1 in balance %}
{% if balance1.wallet_id == wallets1.id %}
<td> {{ balance1.balance }}</td>
{% endif %} {% endfor %}
{% endfor %}
if we have balance of coin we print balance
if balance1.wallet_id need print "0"
The difficulty next. If i do that
{% for wallets1 in wallets %}
<tr>
{% for balance1 in balance %}
{% if balance1.wallet_id == wallets1.id %}
<td> {{ balance1.balance }}</td>
{% else %}
<td> 0</td>
{% endif %} {% endfor %}
{% endfor %}
zero will be printed many times
views
wallets = Wallet.objects.all()
balance = User_balance.objects.filter(user_id= user.id)
args['wallets'] = wallets
args['balance'] = balance
return render_to_response("coins.html", args, user.id)
model
class Wallet(models.Model):
name = models.CharField(max_length=100)
class User_balance(models.Model):
user_id = models.IntegerField()
wallet_id = models.IntegerField()
balance = models.CharField(max_length=100)
You didn't post your view nor models so we have to assume a couple things but basically you're doing it wrong. Since balances have a foreign key on wallets, you don't have to loop over all balances for each wallets, you can just use the reverse relationship:
{% for wallet in wallets %}
<tr>
{% for balance in wallet.balance_set.all %}
<td> {{ balance.balance }}</td>
{% else %}
<td> 0</td>
{% endfor %}
</tr>
{% endfor %}
you must annotate balance in your view like this
wallers = Wallet.objects.all().annotate(total_balance=models.Count('balance'))
...
return render(request, 'template.html', {"wallets": wallets})
then in your html print wallets like this
<table>
<tr><th>wallet</th><th>balance</th></tr>
{% for wallet in wallets %}
<tr>
<td>{{ wallet.name }}</td>
<td>{{ wallet.total_balance|default:0 }}</td>
</tr>
{% endfor %}
</table>

How can I show daily schedules of all users in Django?

I'm using Django to make a website for gym trainers.
what I want is a template for the daily schedules of all trainers like this
But, my page is
The problem is the 'td' of per trainer's tr repeats as many as the number of schedules the trainer has. I know the {% for sc in schedules %} is the problem. But, because schedules are the query set, I should use the for and while using for, I should check the right time to insert the schedule to the right tr, td position. How can I make the successful table to show the daily schedules of all users(trainers)?? Anybody will be very helpful to me.
Schedule.model
class Schedule(models.Model):
Trainer = models.ForeignKey(settings.AUTH_USER_MODEL,blank=True,null=True, related_name='schedule', on_delete=models.SET_NULL)
title = models.CharField(max_length=12,blank=True,)
start = models.DateTimeField(null=True, blank=True)
my views.py
def staff_daily_schedule_search(request):
all_schedules = Schedule.objects.all()
Fitness_list = User.objects.filter(groups__name='Fitness') # Fitness Trainers
search_date1 = request.GET.get('search_date','')
search_date= datetime.datetime.strptime(search_date1, '%Y-%m-%d') #%T = %H:%M:%S '%Y-%m-%d'
schedules= Schedule.objects.none()
for f in Fitness_list:
sc = f.schedule.filter(start__year=search_date.year).filter(start__month = search_date.month).filter(start__day = search_date.day)
print(sc)
schedules |= sc
context = {
'search_date' : search_date1 if search_date1 else datetime.date.today(),
'Fitness_list':Fitness_list,
'schedules' : schedules,
}
return render(request, 'management/staff_daily_schedule.html', context)
staff_daily_schedule.html
<form action="{% url 'management:staff_daily_schedule_search' %}" method="GET">
<span><input type="date" class="search_date my-control" name="search_date" value="{{ search_date }}" ></span>
<a id="today" class="btn btn-warning">오늘</a>
<button class="btn btn-info" value="검색" >검색</button>
</form>
<table class="table table-bordered">
<thead>
<tr>
<th></th>
<th>06:00 </th>
<th>07:00 ~ 07:50</th>
<th>08:00 ~ 08:50</th>
<th>09:00 ~ 09:50</th>
<th>10:00 ~ 10:50</th>
</tr>
</thead>
<tbody>
{% for trainer in Fitness_list %}
<tr>
<td>{{ trainer }} </td>
{% for sc in schedules %} <!-- because of this for, td repeats as many as the number of schedule per trainer has..-->
{% if sc.Trainer == trainer %}
{% if sc.start.hour == 21 %} <!--HOUR of 6:00 a.m = 21-->
<td>{{ sc }}</td>
{% else %}
<td ></td>
{% endif %}
{% if sc.start.hour == 22 %}
<td>{{ sc }}</td>
{% else %}
<td ></td>
{% endif %}
{% if sc.start.hour == 23 %}
<td>{{ sc }}</td>
{% else %}
<td ></td>
{% endif %}
{% if sc.start.hour == 0 %} <!-- 9 a.m. -->
<td>{{ sc }}</td>
{% else %}
<td></td>
{% endif %}
{% if sc.start.hour == 1 %}
<td>{{ sc }}</td>
{% else %}
<td></td>
{% endif %}
{% endif %}
{% endfor %}
</tr>
{% endfor %} <!-- tr repetition as trainers number-->
</tbody>
</table>
The problem
If you put the logic in your view instead of the template, it's easy to set up the table exactly like you want it.
[Edited to use an OrderedDict to preserve the order of trainers.]
views.py
def staff_daily_schedule_search(request):
Fitness_list = User.objects.filter(groups__name='Fitness') # Fitness Trainers
search_date1 = request.GET.get('search_date','')
search_date= datetime.datetime.strptime(search_date1, '%Y-%m-%d') #%T = %H:%M:%S '%Y-%m-%d'
trainer_dict = OrderedDict()
# Initialize each row of the table with the trainer's name and a blank schedule
for f in Fitness_list:
trainer_dict[str(f.id)] = {'name': f.get_full_name(), 'hour_21': '',
'hour_22': '', 'hour_23': '', 'hour_0': '', 'hour_1': ''}
schedules = Schedule.objects.filter(start__year=search_date.year).filter(start__month =
search_date.month).filter(start__day = search_date.day)
# Insert each schedule item into the appropriate table row and cell
for sc in schedules:
trainer_dict[str(sc.Trainer.id)]['hour_' + str(sc.start.hour)] = sc.title
context = {
'search_date' : search_date1 if search_date1 else datetime.date.today(),
'trainer_dict': trainer_dict
}
return render(request, 'management/staff_daily_schedule.html', context)
staff_daily_schedule.html
<form action="{% url 'management:staff_daily_schedule_search' %}" method="GET">
<span><input type="date" class="search_date my-control" name="search_date" value="{{ search_date }}" ></span>
<a id="today" class="btn btn-warning">오늘</a>
<button class="btn btn-info" value="검색" >검색</button>
</form>
<table class="table table-bordered">
<thead>
<tr>
<th></th>
<th>06:00 </th>
<th>07:00 ~ 07:50</th>
<th>08:00 ~ 08:50</th>
<th>09:00 ~ 09:50</th>
<th>10:00 ~ 10:50</th>
</tr>
</thead>
<tbody>
{% for trainer in trainer_dict %}
<tr>
<td>{{ trainer.name }}</td>
<td>{{ trainer.hour_21 }}</td>
<td>{{ trainer.hour_22 }}</td>
<td>{{ trainer.hour_23 }}</td>
<td>{{ trainer.hour_0 }}</td>
<td>{{ trainer.hour_1 }}</td>
</tr>
{% endfor %}
</tbody>
</table>

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

flask wtform field data disappearingappend_entry

Please help - does flask/wtforms somehow treat the data property of a field differently after an append_entry call or am I just really doing this wrong?
I have a form that gets its data from a yaml file. On the initial GET request, the form populates showing the icons from the {% if ifc.poe.data %} as expected. If either button is hit to add a module or interface, the POST re-renders the page, but now ifc.poe.data is empty and thus no icons are rendered. If you comment out the if ifc.xxx.data portion and uncomment out the actual fields, the fields are rendered with the proper data every time. Is this something with how I'm building the form class or in how I'm handling the POST? What happened to the ifc.xxx.data?
Any help is appreciated, I'm pretty new at this.
forms.py
from flask_wtf import Form
from wtforms import Form as wtfForm # Bad hack to get around csrf in fieldlist
class DevInterface(wtfForm):
e_regex = '^ae(\d+)$'
ifc = StringField("Interface", validators=[DataRequired()])
poe = BooleanField('PoE', validators=[Optional()], default=False)
uplink = BooleanField('Uplink', validators=[Optional()],default=False)
desc = StringField("Description", validators=[Optional()],default='')
voip = StringField("VOIP", validators=[Optional()], default='')
etheropt = StringField("LAG interface", validators=[Optional(),Regexp(e_regex, message='Must designate an ae interface, eg. ae4')])
class DevHardware(wtfForm):
module = SelectField('Module', choices=[
('ex2200-24p','ex2200-24p'),('ex2200-48p','ex2200-48p'),
('ex4200-10g','ex4200-10g'),('ex4200-24f','ex4200-24f')],
default='ex2200-48p')
fpc = SelectField('FPC', choices=[(str(i),str(i)) for i in range(10)], default=0)
class DevOptions():
id = StringField('Device Serial Number', validators=[DataRequired()])
hostname = StringField('Hostname', validators=[DataRequired()])
make = SelectField('Make', choices=[('juniper','Juniper')], default = 'juniper')
class AddDev(Form, DevOptions):
modules = FieldList(FormField(DevHardware), min_entries=1)
interfaces = FieldList(FormField(DevInterface), min_entries=1)
add_ifc = SubmitField()
add_module = SubmitField()
views.py
#app.route('/editdev/<vspc>/<dev>', methods=['GET','POST'])
def editdev(vspc,dev):
from skynet.forms import AddDev
try:
d = s.loaddev(dev)
except IOError as e:
flash(dev + ' does not exist.', category='danger')
return redirect(url_for('editvspc', vspc=vspc))
# Have to change up how the data is presented for the form
d['id'] = dev
ifcs = d['interfaces']
del d['interfaces']
l = []
for i in ifcs:
j={}
j['ifc'] = i
j.update(ifcs[i])
l.append(j)
d['interfaces'] = sorted(l, key=lambda k: k['ifc'])
form = AddDev(request.form, data=d)
if form.add_ifc.data:
form.interfaces.append_entry()
elif form.add_module.data:
form.modules.append_entry()
elif request.method == 'POST' and form.validate():
# Placeholder for now
print 'Updated device'
for error in form.errors:
for e in form[error].errors:
flash(e, category='danger')
return render_template('adddev.html', form=form)
template
{% extends "layout.html" %}
{% import "bootstrap/utils.html" as util %}
{% block content %}
{{ super() }}
<div class="container-fluid">
<h1 align='center'>Add Device</h1>
<form method="post" action="">
{{ form.hidden_tag() }}
<div class="form-group">
<table class="table">
<tbody>
<tr>
<td>{{ form.id.label }}</td>
<td>{{ form.id(size=20) }}</td>
</tr>
<tr>
<td>{{ form.hostname.label }}</td>
<td>{{ form.hostname(size=20) }}</td>
</tr>
<tr>
<td>{{ form.make.label }}</td>
<td>{{ form.make}}</td>
</tr>
</tbody>
</table>
{{ form.add_module }}
<table class="table">
<tbody>
{% for field in form.modules.entries %}
<tr>
<td>{{ field.module.label }}</td>
<td>{{ field.module }}</td>
<td>{{ field.fpc.label }}</td>
<td>{{ field.fpc }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<table class="table">
<thead>
<tr>
<th>Interface</th>
<th>Description</th>
<th>PoE</th>
<th>VoIP</th>
<th>LAG</th>
<th>Uplink</th>
</tr>
</thead>
<tbody>
{% for ifc in form.interfaces %}
<tr>
<td>{{ ifc.ifc(size=10) }}</td>
<td>{{ ifc.desc }}</td>
<td>
{% if ifc.poe.data %}
{{ util.icon('flash', style='color:red') }}
{% endif %}
{% if ifc.voip.data %}
{{ util.icon('phone-alt', style='color:green') }}
{% endif %}
{% if ifc.etheropt.data %}
<a class="label label-success">{{ ifc.etheropt.data }}</a>
{% endif %}
{% if ifc.uplink.data %}
{{ util.icon('open', style='color:blue') }}
{% endif %}
</td>
{# <td>{{ ifc.poe }}</td>
<td>{{ ifc.voip }}</td>
<td>{{ ifc.etheropt }}</td>
<td>{{ ifc.uplink }}</td> #}
</tr>
{% endfor %}
</tbody>
</table>
{{ form.add_ifc }}
</div>
<button type="submit" class="btn btn-default">Add Device</button>
</form>
</div>
{% endblock %}

Categories