How do I access a Python created dictionary - python

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

Related

Publish JSON data into a date based table using Flask Jinja2 template

I have JSON data that I want to publish on a webpage in a table format. I'm stuck to validate dates in the jinja template as few dates are missing and data needs to be published under those dates only for which data is available.
JSON DATA I HAVE:
https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/calendarByPin?pincode=241301&date=21-05-2021
[PAGE VIEW I WANT][1]
[1]: https://i.stack.imgur.com/OfVnT.png
MY CODE:
<tbody>
{% for center in centers %}
<tr>
<th scope="row">
<address>
{{ center['name'] }} <br>
{{ center['address'] }}
</address>
</th>
{% for date in dates %}
{% if date == center["sessions"][dates.index(date)]["date"] %}
<td>
{{ center["sessions"][dates.index(date)]["available_capacity"] }} <br>
{{ center["sessions"][dates.index(date)]["min_age_limit"] }} <br>
{{ center["sessions"][dates.index(date)]["vaccine"] }} <br>
</td>
{% else %}
<td>None</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
I have got a solution to this problem. I can preformat data in a new python dictionary rather than direct pushing raw JSON data to the Jinja template, but I'm keener to understand if we can apply any other approach.
You should not add much logic into templates.
There are a few reasons for this:
Best practices. Single responsibility principle.
Good design - application logic independent from the view logic.
Prevent illegible, hard to understand and maintain implementation.
Save your future you from a lot of effort
To be able to do something, especially in a language like Python that allows to mix and go very deep and complex (and even ugly) if you want to, does not mean you should.

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

Cannot access python dictionnary keys in django template

"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.

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