Cannot access python dictionnary keys in django template - python

"Simple" problem here which would already be solved in a view... But I didn't find a way to do it.
So here is the idea; I have Anonymous1, Anymous2... Anymous3 who received calls and communications times on phone numbers. I want to do for each of them a table like that :
Number | Calls | Communication time
2-xxx-x 1 01:00:00
3-xxx-x 23 00:30:00
total 24 01:30:00
Number of calls, communication time and total are all computed in the view, as it has to be dedicated to. I have a list of dictionnaries which contains all the numbers with the numbers of calls, the communication time and its owner. It is looking like that :
list = [{'number':2-xxx-x ,'owner':Anonymous1' ,'calls':1 ,'communication time':datetime object},...]
Why a list of dictionnaries ? Because I am using the regroup template tags as described in the documentation: https://docs.djangoproject.com/fr/1.9/ref/templates/builtins/#regroup
I also make a dictionnary which contains only the total number of calls, the total communication time and the owner; I am using it to compute the sum of each column. Here is it how it looks like :
second_dict = {'Anonymous1':{'calls':24,'communication_time':datetime object}}
To access them, I am using loops in my html code, which is where I have a problem. To create the table, I am regrouping the list of dictionnaries by their owner and performing loops and I am using the dictionnary to make th:
{% regroup list by owner as owner_list %}
{% for owner in owner_list %}
<table class="display" cellspacing="0" style="position: relative; left: -250px;">
<caption> {{owner.grouper}}</caption>
<thead>
<tr>
<th> {% trans "Number" %} </th>
<th> {% trans "Calls"%}</th>
<th> {% trans "Communication time" %}</th>
</tr>
</thead>
<tbody>
{% for item in owner.list%}
<tr>
<td>{{item.number}}</td>
<td>{{item.calls}}</td>
<td>{{item.communication_time}}</td>
</tr>
{% endfor %}
<tr>
{% with owner.list.0.owner as owner_name %}
<td><b>{% trans "Total" %}</b></td>
<td>{{second_dict.owner_name.calls}} </td>
<td> {{second_dict.owner_name.communication_time}} </td>
{% endwith %}
</tr>
</tbody>
</table>
{% endfor %}
As you can see with the code, I want to access the second dictionary values with owner as a key, following what is described here : https://docs.djangoproject.com/en/dev/ref/templates/api/
The problem is... this is not working at all ! I was thinking it was a str/unicode problem, but moving from one to the other when creating the different dictionnaries in the python views did not change anything.
Anyone got an hint on how to solve this ?

You cannot do lookup in a dictionary in template using a variable, dict in template would always treat what's after the dot as a string lookup like second_dict['owner_name']. You need to write a template filter to do it. Check django doc on how to write custom filter.

Related

How can I access nested JSON object in Django Template properly?

I'm trying to access some info with dot notation but I'm getting a weird error. I'll try to explain as well as I can with my code.
My relevant code from views.py file:
def index(request):
// removed "x" assignment as it is long an irrelevant
month = (datetime.datetime.now()).strftime("%B")
year = str(datetime.datetime.now().year)
customers = table(x, month, year)
return render(request, 'index.html', {'customers': customers, "month" : month, "year": year})
Here, I call my tablequery file with table function to return a JSON object of files I have from MONGODB(I am not using MONGODB as the default DB so I do it manually). My table function is as follows:
def table(user, month, year):
///// Code to access DB removed
curs = col.find()
list_curs = list(curs)
liststring = json.dumps(list_curs)
liststring = re.sub("_", "", liststring) // have to remove _ from "_id" because template doesnt allow "_id" type of variable to be used with dot notation
jt = json.loads(liststring)
return jt
Type of "jt" appears to be "list" in python when I print it.
My relevant html code:
<tbody>
{% for customer in customers %}
<tr class="gradeX">
<td>{{ customer.id }}</td>
<td>{{ customer.isim }}</td>
<td>
{% for ekran in customer.ekranlar %}
<li>
{{ ekran }} DENEME
{{ customer.ekranlar.1.hesapbakiyeTL}} TL
{{ customer.ekranlar.1.yurtdisibakiyedolar}} USD
{{ customer.ekranlar.1.yurtdisibakiyeeuro }} Euro
</li>
{% endfor %}
</td>
<td>{{ customer.temsilci }}</td>
<td>
<li>{{ customer.toplambakiyeTL }} TL</li>
<li>{{ customer.toplambakiyeUSD }} USD</li>
<li>{{ customer.toplambakiyeEURO }} EURO</li>
</td>
<td> </td>
<td>
<i class="md md-delete"></i>
<i class="md md-edit"></i>
</td>
</tr>
{% endfor %}
</tbody>
Problem lies within the second for-in loop. When I write "ekran" in customer.ekranlar, I only get the "1", "2", "3" etc as output, but not the values for those. There are more variables within those nested objects(? maybe not objects) but I can only access them if I do "customer.ekranlar.1.hesapbakiyeTL" but when I do "ekran.hesapbakiyeTL"(because I need them looped an printed in table cell) I dont get anything because "ekran" is only "1" or "2" or whatever else the name of the "ekran" is but not the values inside.(I have 4 different accesses as tests to see what is visible how, so it's not the final form)
What I think it should be is like I said, "ekran.hesapbakiyeTL" should be able to access that value, but "ekran" only gets the key, not the nested keys/values inside it. I tried so many different things, tried to change the tablequery output type but I get different problems that way, tried to us "forloop.counter" to use as index to access directly as "customer.ekranlar.forloop.counter" but it appears variables cannot be used in dot notation and many others I've forgotten in the last week. Please, I've been stuck trying to access those values within the for-in loop which stops me from going forward with my project and add other functions.
An example document directly from MongoDB Compass app:
Image for data example
Blues: float numbers
Blacks: strings
There can be more in "ekranlar" as in 1, 2, 3...
All help is appreciated.
Thank you all and have a good day
edit1: I tried to get nested values seperately from python. Same things happens. As soon as I use a second for loop to access like "{{ for ekranlar in customer.ekranlar }}, I only get the key values, not the other variables or their content inside
edit2: How I got around it is that I created a custom tag and sent the customer info to a python file in templatetags with forloop.counter and returned needed info that way. Feels a little clunky but works so meh... If anyone gets around to why this happens inside template html, I'd still love to hear it.

Is there a way to have parallel for loops in HTML?

I am using Python FLask to build a webapp and I am trying to push a nested list to a table in HTML.
Python
item = [[22-03-20, $1409.50, 22-03-20], [22-03-20, $60.00, 22-03-20]]
current HTML
{% for rows in item %}
<tr>
<th scope="row">•</th>
{% for cell in rows %}
<td>{{cell}}</td>
{% endfor %}
<td>edit</td>
</tr>
{% endfor %}
The reason for a duplicate of dates in the nested list is because I need to create a special route page to the date itself.
Output I want to achieve
Basically, the edit will redirect to the page to the respective date. As I have multiple expenses of the same date, I can't just use the unique id within the table.
PROBLEM
The current HTML I have is able to output the 3 items I need, date, expense, date but I can't put a URL redirect to the 3rd variable, date. Is there a way to have 2 for loops running parallel to each other, so I could go through 2 lists at the same time? or is there a better way to do what I want to achieve?
Found a way looking through the documentation again, don't need a parallel for loop actually. I changed the nested list to a tuple in a list. Not sure if this is the best way to do it though.
Python
item = [(22-03-20, $1409.50, 22-03-20), (22-03-20, $60.00, 22-03-20)]
HTML
{% for x,y,z in item %}
<tr>
<th scope="row">•</th>
<td>{{x}}</td>
<td>{{y}}</td>
<td>edit</td>
</tr>
{% endfor %}
I think you should use a list of maps.
item = [
{
'date':'22-03-20',
'price':'$1409.50',
'href':'URI'
},
{
'date':'22-03-20',
'price':'$60.00',
'href':'URI'
},
]
so,
{% for row in item %}
<tr>
<th scope="row">•</th>
<td>{{row.date}}</td>
<td>{{row.price}}</td>
<td>
edit
</td>
</tr>
{% endfor %}

How do I access a Python created dictionary

I have followed the code here https://learn.microsoft.com/en-us/outlook/rest/python-tutorialnd and it works however I need to access the calender events for my own purpose.
context = { 'events': events['value'] }
return render(request, 'tutorial/events.html', context)
The HTML is
<table class="table">
<tr>
<th>Subject</th>
<th>Start</th>
<th>End</th>
</tr>
{% for event in events %}
<tr>
<td>{{ event.subject }}</td>
<td>{{ event.start.dateTime }} ({{ event.start.timeZone }})</td>
<td>{{ event.end.dateTime }} ({{ event.end.timeZone }})</td>
</tr>
{% endfor %}
</table>
My question is how can I interrogate context to obtain the data in the format shown above? Ie subject start date time and end date time.
I'm very new to Python.
I've seen how the data is held using debug statements.
See above
I need interrogate context to obtain the data in the format shown above? Ie subject start date time and end date time.
The data in Context looks like this
context data
How does the data get interpreted by the HTML?
From understanding the code above, events['value'] seems like a list of dictionaries. In the python code, you should be able to access it using
for inner_dict in events['value']:
print(inner_dict["subject"])
print(inner_dict["start"]["dateTime"])
print("*****")
The HTML code perhaps interprets it using Template Engine what does {% %} mean in html

How to switch off Description column in Django Rest Framework Documentation?

Is it possible to switch off Description column in Django Rest Framework Documentation? As you can see on the screenshot below there is a column Description. It is obvious what username and password mean, so I don't need to add more information, however empty cells don't look well. I would like to switch off it only for this method, because for instance in others I would like to have descriptions. Any ideas how can I do this?
There is no easy way to do this at the moment, since that 'Description' column is set at template level. See this template.
To be able to do this in a nicer way you need to customize rest_framework/docs/link.html, maybe have a template tag to check for a custom flag in here:
{% elif link.fields|with_location:'form' %}
<h4>Request Body</h4>
<p>The request body should be a <code>"{{ link.encoding }}"</code> encoded object, containing the following items.</p>
<table class="parameters table table-bordered table-striped">
<thead>
<tr><th>Parameter</th><th>Description</th></tr>
</thead>
<tbody>
{% for field in link.fields|with_location:'form' %}
<tr><td class="parameter-name"><code>{{ field.name }}</code>{% if field.required %} <span class="label label-warning">required</span>{% endif %}</td><td>{% if field.schema.description %}{{ field.schema.description }}{% endif %}</td></tr>
{% endfor %}
</tbody>
</table>
{% endif %}
But I think this is too much to consider just to have that column removed.

For Loop from database using Jinja2 Template

Goal: {% for loop %} over a list (using Jinja2) and then print out results {{print}} in a HTML table using Bootstrap.
Problem: List is not printing in the template.
In the view_config, I used query .all() to return a list of all the assessment_results objects. They are returning... I confirmed this via terminal/print debugging. However, the for loop is not returning the values needed to populate a table; as read in Jinja2 tutorial. I don't think I need to use a for loop in the view_config as I have seen others do (see here), but I am new to this and am trying to figure out how these two programs (SQLALCHEMY and Jinja2) interact.
An example from the printout after using .all() mentioned above:
[<Assessment_Result(owner='<User(username ='baseball', firstname ='Jen', lastname ='See', email='girl#aol.com')>', assessment='<Assessment(name='Becoming a Leader', text='better decisions')>')>]
view_config code:
views.py
#view_config(route_name='assessment_results', request_method='GET', renderer='templates/assessment_results.jinja2')
def all_assessment_results(request):
with transaction.manager: # < --- THIS WAS THE ISSUE !
assessment_results = api.retrieve_assessment_results()
if not assessment_results:
raise HTTPNotFound()
return {'assessment_results': assessment_results}
Corresponding Jinja2 template using Bootstrap:
assessment_results.jinja2
<div class="container">
<table class="table table-hover">
<thead>
<tr>
<td> Assessment ID </td>
<td> Assessment </td>
<td> Owner </td>
</tr>
</thead>
<tbody>
<tr>
{% for x in assessment_results %}
<td>{{ x.assessments|e }}</td>
<td>{{ x.owners|e}}</td>
{% else %}
<td><em>no users found</em></td>
{% endfor %}
</tr>
</tbody>
</table>
</div>
You should look at the documentation
http://jinja.pocoo.org/docs/dev/templates/#for
You want to iterate over a dict, so consider using iteritems, itervalues or what ever you want.
Also note that your query will not return a dict, it will return a list or rows that matched.
I am also not sure if the for-else works in jinja. But you should avoid using that anyways.

Categories