My issue is that I can't seem to translate the dictionary into a table here's the error:
Could not parse ["appid"] from 'game[''appid"]
HTML code:
<table>
<tr>
<th>Game ID</th>
<th>Game Name</th>
<th>Hours Played</th>
</tr>
{% for game in games %}
{# each game object is a dictionary with "appid", "name " and "playtime_forever" keys #}
<tr>
<td>{{ game["appid"] }}</td>
<td>{{game["name"]}}</td>
<td>{{ game["playtime_forever"] }}</td>
</tr>
</table>
views.py code:
~~~~ There's stuff here but it shouldn't be important. ~~~~
return render(request,'hackathon/SteamAPI.html', game)
When I run the server it shows:
game:
[{u'appid': 4000,
u'has_community_visible_stats': True,
u'img_icon_url': u'd9101cbeddcc4ff06c7fa1936c3f381b0bbf2e92',
u'img_logo_url': u'dca12980667e32ab072d79f5dbe91884056a03a2',
u'name': u"Garry's Mod",
u'playtime_forever': 0},
Django templates do not support [] indexing. Instead of
game["appid"]
you should use
game.appid
The same applies for game.name and game.playtime_forever
As an unrelated note, you should also close your for loop:
</tr>
{% endfor %}
</table>
Dictionary should be accessed this way in Django Templates.
choices = {'key1':'val1', 'key2':'val2'}
<ul>
{% for key, value in choices.items %}
<li>{{key}} - {{value}}</li>
{% endfor %}
</ul>
Related
I am new to django and trying to learn. Looking to see if there is a better way to produce the result wanted. See my example below:
application_list.html - Table Data
<tbody>
{% for app in applications %}
<tr>
<th style="text-align: left;">{{ app.username }}</th>
<td>{{ app.desired_username }}</td>
<td>{{ app.created }}</td>
{% if app.application_status_id == 1 %}
<td><span class="badge bg-secondary">{{ app.application_status }}</span></td>
{% elif app.application_status_id == 2 %}
<td><span class="badge bg-success">{{ app.application_status }}</span></td>
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
See here I am setting the class based on the value of the application status id from the database.
Instead of having multiple if statements, is it possible to place this code elsewhere to process and return the class attribute back to line?
I have tried looking at views.py for the application, but unable to determine how this works. My thoughts were to create a function to return a context value for application_list.
application/views.py
def application_list(request):
"""List of all applications"""
template = 'application/application_list.html'
applications = Application.objects.all()
context = {
'applications': applications,
}
return render(request, template, context)
There are multiple ways to solve this; I'll show you two common ones.
Place the if statement inside the css class tag:
<td><span class="badge {% if app.application_status == 1 %}bg-primary{% elif app.application_status == 2 %}bg-secondary{% endif %}">{{ app.application_status }}</span></td>
Add a property to your model:
# views.py
from django.db import models
class Application(models.Model):
application_status_id = ...
#property
def css_background_class(self):
if self.application_status_id == 1:
return 'bg-primary'
elif self.application_status_id == 2:
return 'bg-secondary'
and use it in the template like so:
<td><span class="badge {{app.css_background_class}}">{{ app.application_status }}</span></td>
Good day,
I'm asking myself, if it's possible to transfer multiple informations as primary-keys inside my template!?
For example, when clicking on a link inside my table...
In this case im transfering the item-id:
<tbody>
{% for item in dataset %}
<tr>
<td>
Item-Name
</td>
</tr>
{% endfor %}
</tobdy>
Now I want to transfer the id and - let's say - the name! Is something like this even possible?
<tbody>
{% for item in dataset %}
<tr>
<td>
Item-Name
</td>
</tr>
{% endfor %}
</tobdy>
And if it's possible, do I have to chage something inside my urls.py? Right now it's looking like this:
path('index/<str:pk>', views.example, name="Example"),
Thanks for all your help and a great day!
Your url should be
{% url 'Examplepage' id=item.id name=item.name %}"
And your path should be
path('index/<str:id>/<str:name>/', views.example, name="Example"),
There is a char field named json_field in Django Model. I am trying to iterate it from the view but it returns only one result as the return statement does. I am trying to figure it out how I can iterate json_field using yield.
the result that Model Object returns like:
id : 1
title : "Some Title"
json_field : [{"key":"value","key2":"value2"},{"key":"value","key2":"value2"}]
created : "Sat Oct 21 2017 14:00:53 GMT+0300 (+03)"
view.py
import json
def MyView(request):
model_query = MyModel.objects.all() or MyModel.objects.filter or exclude...
for item in model_query:
data_item = json.loads(item.json_field)
template = "template.html"
context = {"title":title, "data_item":data_item}
return render(request, template, context)
in template.html
{% for query_item in model_query %}
<table>
<thead>
<tr>
<th>{{ query_item.title }} - {{ query_item.created }}</th>
</tr>
</thead>
<tbody>
<tr>
<th>Some Heading </th>
<th>Some Heading </th>
</tr>
<!-- json data -->
{% for item in data_item %}
<tr>
<th>{{ item.key }}</th>
<td>{{ item.key2|floatformat:2 }}</td>
</tr>
{% endfor %}
<!-- json data -->
</thead>
</table><
{% endfor %}
Any help will be appreciated.
You can prepare dataset for you template.
# Fetch data from db as queryset of dicts
items = list(MyModel.objects.filter().values('title', 'created', 'json_field'))
# Decode json in-place
for item in items:
item['json_field'] = json.loads(item['json_field'])
context = {"title":title, "items": items}
Then interate through items inside your template:
{% for item in items %}
<table>
<thead>
<tr>
<th>{{ item.title }} - {{ item.created }}</th>
</tr>
</thead>
<tbody>
<tr>
<th>Some Heading </th>
<th>Some Heading </th>
</tr>
<!-- json data -->
{% for entry in item.json_field %}
<tr>
<th>{{ entry.key }}</th>
<td>{{ entry.key2|floatformat:2 }}</td>
</tr>
{% endfor %}
<!-- json data -->
</thead>
</table><
{% endfor %}
If you're using PostgreSQL, you can using JSONField. It uses the postgres's jsonb type, which is optimized for keeping a json serializable text.
If not, you still can use django-jsonfield. It almost gives the same functionality, even though some of the cool features of django's JSONField are not available (like this kind of lookups).
If none of these work for you, you can also implement your own JSONField by inheriting from CharField or TextField, and overriding some of the functions. This way, you won't need any of the logics of your field in your views.
Edit:
If you find changing your field hard or don't wanna do it for whatever reason, you can do this in your view:
for item in model_query:
item.loaded_json = json.loads(item.json_field)
then you can use it like a normal field in your template:
{% for query_item in model_query %}
{% for item in query_item.loaded_json %}
<span>{{ item.key }}</spam>
{% endfor %}
{% endfor %}
Hello!
The solution depends on your purposes.
Use comprehensions if you want to construct a list of json arrays:
data_items = [json.loads(item.json_field) for item in model_query]
... or generator of json array:
data_items = (json.loads(item.json_field) for item in model_query)
If you want to have a single array of json objects try this:
data_items = []
for item in model_query:
data_items.extend(json.loads(item.json_field))
Then you can use data_items as a template context.
A little tip: You can utilize JSONField at ORM level if you use PostgreSQL or MySQL. Consider this approach if you plan to make any filter queries on this field. As additional benefit JSON encoding/decoding will be out of box.
Thanks for updating your code!
Now I would restructure the json.load() list of dicts so you can use it. That is better style than mangling in the template.
concatenation is done by:
my_dict = dict()
for d in data_item
my_dict.update( d )
if you want to merge, check this thread:
How to merge two dictionaries in a single expression?
I have a dashboard that lists locations. You can then click on locations to get more details of that location. I am getting a 404 error message though.
http://127.0.0.1:8000/locations/get//
Heres the part of the code I am having issues with.
urls.py
url(r'^accounts/loggedin/locations/all/$', 'assessments.views.locations'),
url(r'^accounts/loggedin/locations/get/(?P<location_id>\d+)/$', 'assessments.views.location'),
views.py
def locations(request):
return render_to_response('dashboard/locations.html', {'locations': Location.objects.all() })
def location(request, location_id=1):
return render_to_response('dashboard/location.html', {'location': Location.objects.get(id=location_id) })
locations.html
{% for p in locations %}
<tr>
<td>{{ p.landlord_agent }}</td>
<td>{{ p.id }}</td>
</tr>
{% endfor %}
To be honest I don't get why it would be location_id, as the database field is just id but thats how the guide showed me to do it and changing it to just id doesn't seem to make a difference
The problem is inside the template. You are having a loop variable called p, not location.
Replace location.id with p.id.
Or, better have this variable called location - more readable and explicit.
Complete template code:
{% for location in locations %}
<tr>
<td>{{ location.landlord_agent }}</td>
<td>{{ location.id }}</td>
</tr>
{% endfor %}
edit your app/urls.py:
url(r'^locations/get/(?P<location_id>[\d]+)/$', 'assessments.views.location')
I am trying to access the elements of an array from within a Django template but I am getting a "field * not found" error. My template syntax is as follows:
<h3>Data:</h3>
<table>
<thead>
<tr><th> Row[0] </th><th> Row[1] </th><th> Row[2] </th></tr>
</thead>
<tbody>
{% for row in info %}
<tr>
<td>{{ row.0 }}</td>
<td align = 'center'>{{ row.1 }}</td>
<td align = 'center'>{{ row.2 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
Reading through my stack trace it looks like the problem is that the template engine is trying to reference the array fields using unicode versions of the subscripts; so that:
{{ row.0 }} is referenced as row[u'0'] rather than row[0]
thereby causing the error.
The exact error is: Caught ValueError while rendering: field named 0 not found
It is occuring at:
current = context
try: # catch-all for silent variable failures
for bit in self.lookups:
try: # dictionary lookup
==> current = current[bit]
except (TypeError, AttributeError, KeyError):
try: # attribute lookup
current = getattr(current, bit)
except (TypeError, AttributeError):
try: # list-index lookup
current = current[int(bit)]
So it isn't getting to the point where it tries the list-index lookup. Why would this be?
You can use nested forloops instead of explicit item indexing:
{% for row in info %}
<tr>
{% for value in row %}
<td {% if forloop.counter > 0 %}align = 'center'{% endif %}> {{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
{{ row.0 }} should be work. if no - write templatetag with your own logic for this:
#register.simple_tag
def get(l, i):
return l[int(i)]