Need 2 values to unpack in for loop; got 4 - python

I'm new to Django, and trying to pass api results (dictionaries within a list) to a template using context.
I have tried doing this
{% if apiList != "Error..." %}
{% for i in apiList %}
{% for key, value in i %}
{{ key }} {{ value }}<br>
{% endfor %}
{% endfor %}
{% endif %}
but I get the error
Need 2 values to unpack in for loop; got 4.
When I do the same code but take out the value, so it just searches for the keys, it works fine and prints out all the keys on a new line. I've also tried the following code:
{% for key, value in apiList.items %}
{{ key }} : {{ value }}
{% endfor %}
but this does not seem to work either, it does not give an error, but nothing shows on the screen.
Any idea how to solve this problem? Here is my code in the views.py
try:
apiList = json.loads(api_request.content)
except Exception as e:
apiList = "Error..."
return render(request, 'financials.html', {'apiList': apiList})
else:
return render(request, 'financials.html', {})
Thanks!
EDIT: Here is an example of the data in apiList:
[
{
date: "2020-09-26",
symbol: "AAPL",
fillingDate: "2020-10-30",
acceptedDate: "2020-10-29 18:06:25",
period: "FY",
revenue: 274515000000,
costOfRevenue: 169559000000,
grossProfit: 104956000000,
grossProfitRatio: 0.382332477278109,
researchAndDevelopmentExpenses: 18752000000,
generalAndAdministrativeExpenses: 19916000000,
sellingAndMarketingExpenses: 0,
otherExpenses: 803000000,
operatingExpenses: 38668000000,
costAndExpenses: 208227000000,
interestExpense: 0,
depreciationAndAmortization: 11056000000,
ebitda: 77344000000,
ebitdaratio: 0.281747809773601,
operatingIncome: 66288000000,
operatingIncomeRatio: 0.241473143544069,
totalOtherIncomeExpensesNet: 803000000,
incomeBeforeTax: 67091000000,
incomeBeforeTaxRatio: 0.244398302460703,
incomeTaxExpense: 9680000000,
netIncome: 57411000000,
netIncomeRatio: 0.209136112780722,
eps: 3.31,
epsdiluted: 3.28,
weightedAverageShsOut: 17352119000,
weightedAverageShsOutDil: 17528214000,
link: "https://www.sec.gov/Archives/edgar/data/320193/000032019320000096/0000320193-20-000096-index.htm",
finalLink: "https://www.sec.gov/Archives/edgar/data/320193/000032019320000096/aapl-20200926.htm"
},

try this (i think this can help you to loop through key, value )
{% for key, value in apiList.iteritems() %}

Related

Get element of list by variable in Django template

I have line of code in Django template:
<h4>{{ totals.date.weekday }}</h4>
Totals is the Python list, how do i get item of this list by index stored in date.weekday?
This would look in Python like this:
totals[date.weekday]
Creating another variable, which stores date.weekday doesn't work
UPD:
I found a solution:
Just added element of totals list to template context in render
For example:
# ...
return render(request, 'template.html', context={'date_total'=totals[date.weekday()]})
You can access the array directly using
{{ totals.0.date.weekday}} where the 0 is the position that you want.
Also if you want to print all the elements in total you will need a for loop such as:
{% for d in totals %}
{{ d }}
{% endfor %}
about sorting, you can use the pipe order_by but I recommend you to pass the list already ordered from the views
You have to run the "for loop" for this.
{% with counts = 0 %}
{% while counts < totals.count %}
{% if counts == date.weekday %}
<h4>total.counts</h4>
{% endif %}
{% counts += 1 %}
{% endfor %}
I did not get your question completely but i think it might help.

Iterating through Python dictionary with Jinja2

I've scoured the internet and can't seem to find the solution that fits my case.
I have a dictionary:
{"1528430400000": 129, "1528516800000": 123.14, "1528603200000": 117.28, "1528689600000": 111.42, "1528776000000": 105.56, "1528862400000": 99.7, "1528948800000": 93.84, "1529035200000": 87.98, "1529121600000": 82.12, "1529208000000": 76.26, "1529294400000": 70.4, "1529380800000": 64.54, "1529467200000": 58.68, "1529553600000": 52.82, "1529640000000": 46.96, "1529726400000": 41.1, "1529812800000": 35.24, "1529899200000": 29.38, "1529985600000": 23.52, "1530072000000": 17.66, "1530158400000": 11.8, "1530244800000": 5.94, "1530331200000": 0.08, "1530417600000": 0}'
where each key is a javascript-formatted date.
I'm looking for a simple iteration through each key and value.
example:
{% for key,value in dict %}
{{key}}, {{value}}
{% endfor %}
Use:
{% for key, value in dict.items() %}
<h1>Key: {{key}}</h1>
<h2>Value: {{value}}</h2>
{% endfor %}
let's suppose your dictionary is "my_dict".
view.py (django) will have-
return render(request, 'template', { 'my_dict' :
my_dict })
HTML page will have-
{% for k,v in my_dict.items %}
{{ k }}: {{ v }} <br>
{% endfor %}
You can pass dict.items to the template rendering object:
return flask.render_template('template_name', data = the_dict.items())
Then, in the HTML:
{%for a, b in data%}
<span>Key: {{a}}, value: {{b}}</span>
{%endfor%}
{% if dict_var |type_debug == 'dict' %}
{% for key in dict_var %}
{{ key }}: "{{ dict_var[key] }}"
{% endfor %}
{% endif %}
use this will error: ValueError: too many values to unpack in sometimes
{% if dict_var |type_debug == 'dict' %}
{% for key, value in dict_var %}
{{ key }}: "{{ value }}"
{% endfor %}
{% endif %}

How can i access a jinja2 variable outside the for loop?

im trying to use a for loop to add up some numbers for each day
and i would like to access the variable outside the for loop im not sure how to go about this I am using the flask framework with python and just come from weppy where this was not a problem is there a way to make it work the same way in flask?
here is some simple code
{% set newtotal = 0 %}
{% for item in daily: %}
{% set newtotal = newtotal + item[10]|float %}
{% endfor %}
<div class="bottom">
<span>Total: {{ newtotal }}</span>
</div>
the numbers collected by item[10] are dollar values
if i place the {{ newtotal }} before the endfor it shows every value as its being added up this is not what I want
EDIT:
if it helps daily is a list of 8 tuples
Please keep in mind that it is not possible to set variables inside a block or loop and have them show up outside of it.
As of version 2.10 this can be handled using namespace objects which allow propagating of changes across scopes.
Here is your code using namespace:
{% set ns = namespace (newtotal = 0) %}
{% for item in daily: %}
{% set ns.newtotal = ns.newtotal + item[10]|float %}
{% endfor %}
<div class="bottom">
<span>Total: {{ ns.newtotal }}</span>
</div>
One solution (probably the "simplest") would be to change your Python script to pass in a variable named newtotal that would simply be the length of the daily list!
Alternatively, you could use the length filter:
{{things|length}}
In which case your code could look something like this:
{% set newtotal = 0 %}
{% for item in daily: %}
{% set newtotal = newtotal + item[10]|float %}
{% endfor %}
<div class="bottom">
<span>Total: {{daily|length}}</span>
</div>
Hope it helps!
Additional Sources:
jinja2: get lengths of list
How do I access Jinja2 for loop variables outside the loop?
EDIT
Sorry, I misread the question!
You can use the sum filter instead ({{ list | sum() }}).
So your code could look like:
{% set newtotal = 0 %}
{% for item in daily: %}
{% set newtotal = newtotal + item[10]|float %}
{% endfor %}
<div class="bottom">
<span>Total: {{ daily | sum() }}</span>
</div>
New sources:
Documentation
Sum elements of the list in Jinja 2
Use the namespace object.
https://jinja.palletsprojects.com/en/master/templates/#assignments
Here’s a working example from my config.
{% set i= namespace(fxp0_ip=0) %}
{% set i= namespace(mgmt_ip = 0) %}
{% set i= namespace(loopback_ip = 0) %}
{% set i= namespace(lan_ip = 0) %}
{% set i= namespace(wan_ip = 0) %}
{% for interface in device_vars.interfaces %}
{% elif interface.name == "ge-0/0/0" %}
{% set i.mgmt_ip = interface.ip_addr %}
{% elif interface.name == "lo0" %}
{% set i.loopback_ip = interface.ip_addr %}
{% elif interface.name == "ge-0/0/2" %}
{% set i.lan_ip = interface.ip_addr %}
{% elif interface.name == "ge-0/0/1" %}
{% set i.wan_ip = interface.ip_addr %}
{% endif %}
{% endfor %}
{{i.mgmt_ip}}
{{i.wan_ip}}

how to iterate through dictionary in a dictionary in django template?

My dictionary looks like this(Dictionary within a dictionary):
{'0': {
'chosen_unit': <Unit: Kg>,
'cost': Decimal('10.0000'),
'unit__name_abbrev': u'G',
'supplier__supplier': u"Steve's Meat Locker",
'price': Decimal('5.00'),
'supplier__address': u'No\r\naddress here',
'chosen_unit_amount': u'2',
'city__name': u'Joburg, Central',
'supplier__phone_number': u'02299944444',
'supplier__website': None,
'supplier__price_list': u'',
'supplier__email': u'ss.sss#ssssss.com',
'unit__name': u'Gram',
'name': u'Rump Bone',
}}
Now I'm just trying to display the information on my template but I'm struggling. My code for the template looks like:
{% if landing_dict.ingredients %}
<hr>
{% for ingredient in landing_dict.ingredients %}
{{ ingredient }}
{% endfor %}
Print {{ landing_dict.recipe_name }}
{% else %}
Please search for an ingredient below
{% endif %}
It just shows me '0' on my template?
I also tried:
{% for ingredient in landing_dict.ingredients %}
{{ ingredient.cost }}
{% endfor %}
This doesn't even display a result.
I thought perhaps I need to iterate one level deeper so tried this:
{% if landing_dict.ingredients %}
<hr>
{% for ingredient in landing_dict.ingredients %}
{% for field in ingredient %}
{{ field }}
{% endfor %}
{% endfor %}
Print {{ landing_dict.recipe_name }}
{% else %}
Please search for an ingredient below
{% endif %}
But this doesn't display anything.
What am I doing wrong?
Lets say your data is -
data = {'a': [ [1, 2] ], 'b': [ [3, 4] ],'c':[ [5,6]] }
You can use the data.items() method to get the dictionary elements. Note, in django templates we do NOT put (). Also some users mentioned values[0] does not work, if that is the case then try values.items.
<table>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
</tr>
{% for key, values in data.items %}
<tr>
<td>{{key}}</td>
{% for v in values[0] %}
<td>{{v}}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
Am pretty sure you can extend this logic to your specific dict.
To iterate over dict keys in a sorted order - First we sort in python then iterate & render in django template.
return render_to_response('some_page.html', {'data': sorted(data.items())})
In template file:
{% for key, value in data %}
<tr>
<td> Key: {{ key }} </td>
<td> Value: {{ value }} </td>
</tr>
{% endfor %}
This answer didn't work for me, but I found the answer myself. No one, however, has posted my question. I'm too lazy to
ask it and then answer it, so will just put it here.
This is for the following query:
data = Leaderboard.objects.filter(id=custom_user.id).values(
'value1',
'value2',
'value3')
In template:
{% for dictionary in data %}
{% for key, value in dictionary.items %}
<p>{{ key }} : {{ value }}</p>
{% endfor %}
{% endfor %}
If you pass a variable data (dictionary type) as context to a template, then you code should be:
{% for key, value in data.items %}
<p>{{ key }} : {{ value }}</p>
{% endfor %}
I am thankful for the above answers pointing me in the right direction. From them I made an example for myself to understand it better. I am hoping this example will help you see the double dictionary action more easily and also help when you have more complex data structures.
In the views.py:
bigd = {}
bigd['home'] = {'a': [1, 2] , 'b': [3, 4] ,'c': [5,6] }
bigd['work'] = {'e': [1, 2] , 'd': [3, 4] ,'f': [5,6] }
context['bigd'] = bigd
In the template.html:
{% for bigkey, bigvalue in bigd.items %}
<b>{{ bigkey }}</b> <br>
{% for key, value in bigvalue.items %}
key:{{ key }} <br>
----values: {{ value.0}}, {{value.1 }}<br>
{% endfor %}
<br>
{% endfor %}
Notice the list in the second dictionary is accessed by the index in the list.
Result in browser is something like:

Decode values of a tuple in django template

if(len(f1) > 0):
for qs in profile_map:
p = Profile.objects.get(pk=qs.emp.id)
t_name = p.first_name + p.last_name
t_arr.append((q.profile.id,emp_name))
response_dictionary.update({'tarr':t_arr})
render_to_response('project/profile_table.html',context_instance=RequestContext(request,{'response_dictionary': response_dictionary}))
In Django template How to deocode all the 1.values of the tuple 2.search the tuple for a certain value in q.profile.id
{% for ele in response_dictionary.tarr%}
alert('{{ele}}');
//Get this as alert (11L, u'Employee3.')
{% endfor %}
In your case, the generator will assign the tuple to ele, so you can access the first, last name with {{ ele.0 }} {{ ele.1 }}.
But this is also legal, to unpack the tuple into two vars:
{% for first_name, last_name in response_dictionary.tarr %}
if you are using django 0.96 you can't have multiple values in for loop. so this will not work:
{% for first_name, last_name in response_dictionary.tarr %}
instead use
{% for ele in response_dictionary.tarr %}
{{ ele.0 }} {{ ele.1 }}
{% endfor %}

Categories