Django Render List of Dictionaries to a template - python

I have a list of dictionaries with same key information. How can I pass this list of dictionaries to a Django template ?
listdict = [{'product':'specs','price':'12'}, {'product':'shoes','price':'30'}]
When trying to send this list via views file to template it fails with an error indicating that only dictionaries are allowed.
Here is the code from views file
return render(request, 'recordings/extensionrecording.html',listDict)
Here is the html block-
<tbody>
{%for list in listDict%}
{%for elements in list%}
<tr>
<td class="body-item fonts-style display-4">{{elements.product}}</td>
<td class="body-item fonts-style display-4">{{elements.price}}</td>
</tr>

Just pass these as an entry of the dictionary:
return render(request, 'recordings/extensionrecording.html',{'listDict': listDict})
Then in the template, you can render these with:
{%for item in listDict %}
{{ item.product }}
{{ item.price }}
{% endfor %}

Related

Unable to read dictionary values in Django template

I have a dictionary that I pass to Django template.
If I render just a dictionary with {{dict}} , then it is rendered fine, like this:
If I render just the keys with {{appoint}}, they are also rendered just fine, like this:
But if I render dictionary values with {{dict.appoint}} then I get nothing
I have read every post here about Django, template language and dictionaries and have not been able to solve this seemingly simple problem.
Render your dict in html like this:
{% for key, value in dict.items() %}
<tr>
<td> {{ key }}: </td> <td> {{ value }} </td>
</tr>
{% endfor %}
you can do with a custom template tag, check in here how to do it https://docs.djangoproject.com/en/3.0/howto/custom-template-tags/

URL Patterns and Views

I have an application which requests data based on certain parameters. I use two functions to handle the requests and then create two objects from the responses. I am able to iterate through each object individually and display the data of a particular object on my webpage, but when I try to use both functions simultaneously, only one function iterates through the object. It is my understanding that this issue has something to do with URL patterns, but I am not as to what the best approach would be. Below you will find my urlpatterns, my functions, and the HTML I use to access the view.
urls.py
urlpatterns = [
path('', views.customer, name='customer'),
path('', views.information, name='information'),
]
views.py
def customer(request):
for i, contact in enumerate(contactObj):
try:
contacts = contactObj
context = {'contacts': contacts}
except KeyError:
print()
return render(request, 'uccx/home.html', context)
def information(request):
for i, ticket in enumerate(ticketObj):
try:
tickets = ticketObj
context = {'tickets': tickets}
except KeyError:
print()
return render(request, 'uccx/home.html', context)
home.html
<tbody>
{% for ticket in tickets %}
<tr class="{% cycle 'row1' 'row2'">
<td> {{ ticket.id }} </td>
<td> {{ ticket.company.name }} </td>
<td> {{ ticket.summary }} </td>
</tr>
{% endfor %}
</tbody>
Your URL patterns should be different for every view. otherwise, it will always call the view which is defined above either you call it by customer or information
So your URL patterns should be
urlpatterns = [
path('customer/', views.customer, name='customer'),
path('information/', views.information, name='information'),
]
UPDATE
You don't have to create separate views for fetching objects from different tables to
show in a webpage
Create a single view and send as many objects in context dictionary.
def table_content(request):
...
# fetch objects here from model
contacts = Contact.objects.all()
tickets = Ticket.objects.all()
# set objects to context dictionary
context = {'contacts': contacts, 'tickets' : tickets}
return render(request, 'uccx/home.html', context)
Now in your template, you can easily loop over tickets and contacts
{% for ticket in tickets %}
<tr>
<td> {{ ticket.id }} </td>
...
</tr>
{% endfor %}
{% for contact in contacts %}
<tr>
<td> {{ contact.id }} </td>
...
</tr>
{% endfor %}

Django - printing multiple passed lists from views.py

I have 4 lists with the same length and would like to pass all of them to the html page.
views.py
return render(request, 'result.html', {'listA':listA, 'listB':listB, 'listC':listC, 'listD':listD})
And here is the code when I tried with Flask.
app.py
return render_template('result.html', listA = listA, listB = listB, listC = listC, listD = listD)
Below is the code in the template file; with Flask, it prints out the table without any problems, but it doesn't seem to work with Django.
How should I fix my code?
result.html
{% for i in listA %}
<tr>
<th> {{ listA[loop.index] }} </th>
<td> {{ listB[loop.index] }} </td>
<td> {{ listC[loop.index] }} </td>
<td> {{ listD[loop.index] }} </td>
</tr>
{% endfor %}
You should use a custom templatetag for implementing lookup, because django does not provide one for you.
and then use django template engine for loop for getting forloop.counter0
First create templatetags directory with __init__.py inside your app folder. Lets assume your app is called polls folder structure will look like this:
polls/
__init__.py
models.py
templatetags/
__init__.py
lookup.py
views.py
After write lookup code which goes inside lookup.py:
from django import template
register = template.Library()
#register.filter
def lookup(d, key):
return d[key]
And finlly use it in template file:
{% load lookup %}
...
{% for i in listA %}
<tr>
<th> {{ listA|lookup:forloop.counter0 }} </th>
<td> {{ listB|lookup:forloop.counter0 }}</td>
<td> {{ listC|lookup:forloop.counter0 }}</td>
<td> {{ listD|lookup:forloop.counter0 }}</td>
</tr>
{% endfor %}
...
Ref 1 - Get list item dynamically in django templates
Ref 2 - Custom template tag example
Ref 3 - Django templatetag
Ref 4 - Django template for loop

Using the slice filter with context data from a Django QuerySet

I am trying to split a list from my model across two columns, using this html code in the template:
< div class ="col-md-6" >
{%for value in object_list %}
<ul>< ahref="/sites/{{value.url}}/">{{value.Site}}</a></ul>
{% endfor %}
I was planning to achieve this with the slice tag to filter the list, e.g.:
{%for value in object_list|slice:"10:20" %}
It does not work however, and I think it might be because I have context data i.e. {{value.Site}}, instead of just {{Site}} for example. This is the corresponding view:
class homeview(ListView):
template_name = 'annual_means/home.html'
def get_queryset(self):
return AnnualMean.objects.values("Site", "url").distinct()
What do I need to do to get the slice to work?
I think, what you need is this:
<table>
<tr>
<th>URL</th>
<th>SITE</th>
</tr>
{% for value in object_list %}
<tr>
<td>{{value.url}}</td>
<td>{{value.Site}}</td>
</tr>
{% endfor %}
</table>
URLs and Sites will be displayed as a table.

How to send zipped list in context (Django)

I am trying to send a zipped list in context to my HTML template. But I'm only seeing the data of the latest object and not all the objects. Document is my model name.
I am trying to scrape a HTML page and the values I've received are being stored in list (I'm using lxml to parse).
Here is the relevant code from views.py
query_results=Document.objects.order_by('-id')
zipped=Document.objects.all().distinct().values_list('zipped')
context ={
"query_results": query_results, "zipped": zipped,
}
return render(request, "result.html", context)
Here is how I'm displaying the data in my template's table.
{% for item in query_results %}
<tbody>
<tr>
<td>...</td>
.
.
<td colspan="2">
{% for i,j in zipped %}
<b>{{ i }}</b> : {{ j }}<br><br>
{% endfor %}
</td>
.
.
</tr>
</tbody>
{% endfor %}
This is how I zipped the two lists.
Mymodels=Document()
Mymodels.zipped = zip(Mymodels.anchortext,Mymodels.anchorlink)
I'm supposed to get different values for my 3 rows but I'm getting the same value for all the 3 rows. The other values are fine only the zipped values are the same.
Any help would be greatly appreciated.

Categories

Resources