how to use 2dicts in a for loop in Django template? - python

I have context as below :
context = {
'author': author,
'books':books,
}
Now I need to use author and books in One for loop like this :
{% for each in ***author & books*** %}
<tr>
<td>{{ each.author.name }}</td>
<td>{{ each.book.name }}</td>
<td>{{ each.book.pubishDate }}</td>
</tr>
{% endfor %}
How to make such a for loop in Django template?
Thanks all.

join 2 dictionaries into a list before sending it to the template(i.e in the view):
dicts = [dict1, dict2]
and try this:
{% for d in dicts %}
<tr>
<td> {{ d.x }} </td>
<td> {{ d.y }} </td>
</tr>
{% endfor %}

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

Get the last used value of the forloop counter

I'm using the forloop counter to assign unique ids to three which I later populate with data.
<tbody>
{% for d in data %}
<tr>
<td id="menge{{ forloop.counter }}">{{ d.menge }}</td>
<td id="preis{{ forloop.counter }}" name="preis">{{ d.preis }}</td>
<td>{{ d.einheit }}</td>
<td id="preisprostuekc{{ forloop.counter }}" name="{{ d.id}}">
</td>
</tr>
{% endfor %}
</tbody>
Lets say the loop runs 10 times. This means the last assigned value is 10. Can i get that value, the last value of the counter, to reuse it in a javascript function? If yes: how? Thanks!
Normally if data is an iterable where one can call len(…) on, you can use this to determine the number of objects, so you can use the |length template filter:
<script language="JavaScript">
var value = {{ data|length }};
</script>
You can use forloop.last
Like this:
{% for d in data %}
{% if forloop.last %}
<div>Last number = {{ forloop.counter }} </div>
{% endif %}
{% endfor %}

How to iterate over a list in django templates? [duplicate]

This question already has answers here:
Using index from iterated list
(2 answers)
Closed 7 years ago.
I'm passing 4 lists of the same length and the length of the lists to my template. How do I iterate over the lists?
views.py
def allbooks(request):
ID = [1,2]
bookName = ["Python", "Java"]
author = ["idk", "who"]
copies = [3,7]
return render(request, 'allbooks.html',{'ID':ID,'bookName':bookName, 'author':author, 'copies':copies,'range':range(len(ID))})
allbooks.html
{% extends 'base.html' %}
{% block content %}
{% if user.is_authenticated %}
<div>
<h3>
List of books:
</h3>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Book Name</th>
<th>Author</th>
<th>Number of copies</th>
</tr>
</thead>
<tbody>
{% for x in range %}
<tr>
<td>{{id[x]}}</td>
<td>{{bookName[x]}}</td>
<td>{{author[x]}}</td>
<td>{{copies[x]}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<h3>You must login to continue.</h3>
{% endif %}
{% endblock %}
I've tried replacing the variable x with {% forloop.counter0 %} but to no avail. How can I fix this?
Zip all your lists to one list of tuples:
books= zip(ID, bookName, author, copies)
return render(request, 'allbooks.html',{ "books": books} )
Than loop over it in templates like:
{% for book in books %}
<tr>
<td>{{ book.0 }}</td>
<td>{{ book.1 }}</td>
<td>{{ book.2 }} </td>
<td>{{ book.3 }}</td>
</tr>
{% endfor %}
I suggest a better structure for your book info:
books = [
{ "id":1, "name": "Python", "author":"idk", "copies": 1},
{ "id":2, "name": "Java", "author":"idk2", "copies": 3}
]
than iterate through it:
{% for book in books %}
<tr>
<td>{{ book.id }}</td>
<td>{{ book.name }}</td>
<td>{{ book.author }} </td>
<td>{{ book.copies }}</td>
</tr>
{% endfor %}

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

How can I iterate multiple key from a dictionary in Django template

I have given data from views to template in django. I want to iterate these multiple keys to build a html table.
views.py
data={'pacientes':p,'inicios':i,'finales':f,'enfermedad':enf} # p, i and f are lists
return render(request,'verEnf.html',data)
I want to do something like
index.html
<table>
{% for p, i, f in pacientes, inicios, finales %} # I know that this code is not work
<tr>
<td>{{ p.nombre }}</td>
<td>{{ i }}</td>
<td>{{ f }}</td>
<tr>
{% endfor %}
</table>
p is an object from Pacientes
class Usuario(models.Model):
dni=models.CharField(max_length=9,primary_key=True)
clave=models.CharField(max_length=16)
nombre=models.CharField(max_length=30)
...
and i is a string's list as
('20-2-2014', '12-2-2014', ..., '11-5-2014')
I suppose that each index of paciente, inicio and finales are related between them.
Just as Ignacio says, you can write some code in the view, before passing it to the template in order to solve your problem.
A possible solution could be packing the values in a list of tuples like this:
[
(pacientes[0], inicios[0], finales[0]),
(pacientes[1], inicios[1], finales[1]),
...
]
You can achieve this easily by using the zip function in your view:
pacientes_data = zip(p, i, f)
data={'pacientes_data':pacientes_data,'enfermedad':enf} # p, i and f are lists
return render(request,'verEnf.html',data)
And in your template:
<table>
{% for p,i,f in pacientes_data %}
<tr>
<td>{{ p.nombre }}</td>
<td>{{ i }}</td>
<td>{{ f }}</td>
</tr>
{% endfor %}
</table>
Here is a working solution for similar task:
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Model Name</th>
<th scope="col">Device Count</th>
</tr>
</thead>
<tbody>
{% for all_model in all_models %}
<tr>
<th scope="row">{{ forloop.counter }}</th>
<td>{{ all_model.0 }}</td>
<td>{{ all_model.1 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
In view.py
all_models = []
all_models_names = [1,2,3,4]
all_models_names_values = [1,2,3,4]
all_models = zip(all_models_names,all_models_names_values)
return render(request, "sample.html",{'all_models':all_models})

Categories