Django view: How to display data from a dictionary - python

I've got a dictionary like {'a':{'c':2, 'd':4 }, 'b': {'c':'value', 'd': 3}}
How can I display this into a table in view?

Question is answered here:
In summary you access the code as you would for a python dictionary
data = {'a': [ [1, 2] ], 'b': [ [3, 4] ],'c':[ [5,6]] }
You can use the dict.items() method to get the dictionary elements:
<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>

Depends on how you want to do it. In Django templates, you access keys the same way you access a method. That is, Python code like
print my_dict['a']['c'] # Outputs: 2
becomes
{{ my_dict.a.c }} {# Outputs: 2 #}
in Django templates.

Had a similar problem and I solved it this way
PYTHON
views.py
#I had a dictionary with the next structure
my_dict = {'a':{'k1':'v1'}, 'b':{'k2': 'v2'}, 'c':{'k3':'v3'}}
context = {'renderdict': my_dict}
return render(request, 'whatever.html', context)
HTML
{% for key, value in renderdict.items %}
<h1>{{ key }}</h1>
{% for k, v in value.items %}
<h1>{{ k }}</h1>
<h1 > {{ v }}</h1>
{% endfor %}
{% endfor %}
The outputs would be
{{ key }} = a
{{ k }} = k1
{{ v }} = v1 #and so forth through the loop.

Related

Django. Access list index in child for loop

How can I change the accessed index of an inner for loop list based on a counter from the outer loop? In normal python I would do something like
parent_list = ['One','Two','Three']
child_list = ['A','B','C']
for idx, item in enumerate(parent_list):
for child_item in child_list[idx]:
print(str(idx), item, child_item)
I've been looking at using with and forloop.counters but I either run into the index not being accessed or index not changing. This is what I currently have.
{% for item in payout_items %}
{% with forloop.counter0 as outer_counter %}
<h2>{{ item.market_place }} on {{ item.entry_date }}:
{% for item in royalty_items.outer_counter %}
<tr>
<th scope="row">{{ item.id }}</th>
<td>{{ item.entry_date }}</td>
<td>{{ item.market_place }}</td>
</tr>
{% endfor %}
{% endwith %}
{% endfor %}
If I change
{% for item in royalty_items.outer_counter %}
to
{% for item in royalty_items.0 %}
I get the first index repeated many times. I can see that outer_counter is incrementing from the output but just need royalty_items to increment the accessed index as well.
As requested the view is
detail_object = AccountingPeriod.objects.get(pk=detail_id)
payout_items = Payout.objects.filter(sales_period_start__range=[detail_object.period_start, detail_object.period_end])
royalty_items = []
for payout in payout_items:
temp = Royalty.objects.filter(entry_date__range=[payout.sales_period_start, payout.sales_period_end]).filter(market_place=payout.market_place)
print(str(payout.sales_period_start) + " - " + str(payout.sales_period_end) + " - " + payout.market_place + " = " + str(len(temp)))
royalty_items.append(temp)
And the following render call is passed.
render(request, 'royalties/accounting_period/summary.html', {'detail_object': detail_object, 'payout_items': payout_items, 'royalty_items': royalty_items})
Solution: I created a template filter but feel there should be a more elegant answer.
#register.filter()
def getRoyaltySet(royalty_items, outer_counter):
return royalty_items[outer_counter]
I would just add this to the items, so:
detail_object = get_object_or_404(AccountingPeriod, pk=detail_id)
payout_items = Payout.objects.filter(
sales_period_start__range=(
detail_object.period_start,
detail_object.period_end,
)
)
for payout in payout_items:
temp = Royalty.objects.filter(
entry_date__range=(payout.sales_period_start, payout.sales_period_end),
market_place=payout.market_place,
)
print(
f'{payout.sales_period_start} - {payout.sales_period_end} - {payout.market_place} = {len(temp)}'
)
payout.royalities = temp
Then you can access this through .royalities:
{% for item in payout_items %}
<h2>{{ item.market_place }} on {{ item.entry_date }}</h2>:
{% for subitem in item.royalites %}
<!-- … -->
{% endfor %}
{% endfor %}
You can use forloop.parentloop to get to the outer forloop
{{ forloop.parentloop.counter }}
You can even chain them if you have nested loops:
{{ forloop.parentloop.parentloop.counter }}
If you wanna absolutely use your own index you can access the dictionary with .items:
{% for key, value in mydict.items %}
{% for key2, value2 in otherdict.items %}
<div>{{ key }} - {{ key2 }}</div>
{% endfor %}
{% endfor %}

I want to print both, keys and values of dictionary which I pass in render to a HTML page in Django

This loop format in html is only printing the key but not value,I want to print both key and value in html page.
views.py
def predict(request):
if request.method == "POST":
dict = {'Name': John, 'Age': 40}
return render(request,'standalone.html',{'content':dict})
else:
return render(request,'test_homepage.html')
satandalone.html
{% for c in content %}
{{c}}
{% endfor %}
You use .items() to obtain an iterable of 2-tuples.
def predict(request):
if request.method == "POST":
data = {'Name': 'John', 'Age': 40}
return render(request,'standalone.html',{'content': data.items()})
else:
return render(request,'test_homepage.html')
In the template, you can then render this with:
{% for k, v in content %}
{{ k }}: {{ v }}
{% endfor %}
Note: Please do not name a variable dict, it overrides the reference to the dict
class. Use for example data.
Try this in your template satandalone.html:
{% for c in content %}
{{ c.name }}
{{ c.age }}
{% endfor %}
Try this. It might help you.
{% for key, value in content.items %}
{{ key }}: {{ value }}
{% endfor %}

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

Django template and part of a dictionary of lists

in Django I want to display some entries in a dictionary of lists.
My context is:
keys = ['coins', 'colors']
dict = {'colors':['red', 'blue'],
'animals':['dog','cat','bird'],
'coins':['penny','nickel','dime','quarter'] }
Template code:
<ul>{% for k in keys %}
<li>{{ k }}, {{ dict.k|length }}: [{% for v in dict.k %} {{ v }}, {% endfor %}]
{% endfor %}</ul>
I want to see:
* coins,4: [penny, nickel, dime, quarter,]
* colors,2: [red, blue,]
But what I actually see is keys but no values:
* coins,0: []
* colors,0: []
Note: I also tried dict.{{k}} instead of dict.k, but as expected that just gave a parse error in template rendering. I'll get rid of the trailing comma with forloop.last after getting the basic list working.
What is the secret sauce for displaying selected values from a dictionary of lists?
The question django template and dictionary of lists displays an entire dictionary, but my requirement is to display only a few entries from a potentially very large dictionary.
The problem (as you suspected) is that dict.k is evaluated to dict['k'] where 'k' is not a valid key in the dictionary. Try instead to iterate each item pair using dict.items and only display the results for the keys you're concerned with:
<ul>{% for k, v in dict.items %}
{% if k in keys %}
<li>
{{ k }}, {{ v|length }}: [{% for val in v %} {{ val }},{% endfor %}]
</li>
{% endif %}
{% endfor %}
</ul>
<ul>
{% for k, v in dict.items %} # instead of iterating keys, iterate dict
{% if k in keys %} # if key found in keys
<li>
{{ k }}, {{ v|length }}: [{% for val in v %} {{ val }},{% endfor %}]
</li>
{% endif %}
{% endfor %}
</ul>

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:

Categories