I have a queryset full of weather objects and I need to loop through a custom array to extract specific weather metrics in each of the weather objects in an HTML template for a Django application.
detail.html
<table>
<tr>
{% for weather_object in weather_objects %}
{% for variable in variable_list %} ## variable_list = ['temp', 'humidity']
<td>{{weather_object.variable}}</td>
{% endfor %}
{% endfor %}
</tr>
</table>
Views.py
context = {'weather_objects': weather_objects,
'variable_list': variable_list}
return render(
request,
'webapp/detail.html',
context=context
)
There could be better ways to do this, but honestly, I'm really stumped here. Why can't I loop through the variable list and extract data from weather_object? It's specifically 'weather_object.variable' that just acts nonexistent.
I can do it manually, I can write specifically
<td>{{weather_objects.temp}}</td>
or
<td>{{weather_objects.humidity}}</td>
but I can't automate it in a for a loop. Why?? I have verified that the variables in the variable list are correct and should work. Could it be because the variable is only a string substitute?
CodePudding user response:
If you write:
{{weather_object.variable }}
it aims to obtain the attribute named variable
from the weather_object
, and if that fails, it will try to use weather_object['variable']
. The fact that there is a variable named variable
does not matter. That would also be very unstable: imagine that you assign a variable named humidity = 'temp'
. It would easily break the application since now all item.humidity
s all of a sudden should use item.temp
instead. That would be bad code design.
However a template should not implement business logic: it should only implement rendering logic. It is the view that needs to pass data in an accessible way to the view.
You for example can construct a list of lists for your weather_objects
with:
variable_list = ['temp', 'humidity']
weather_data = [
[getattr(datum, v) for v in variable_list]
for datum in wheather_objects
]
context = {'weather_data': weather_data }
return render(
request,
'webapp/detail.html',
context=context
)
and then render this as:
<table>
{% for weather_object in weather_data %}
<tr>
{% for item in weather_object %}
<td>{{ item }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>