1

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?

1
  • because {{ weather_object.variable }} will look for weather_object.variable (so an attributed named variable), and weather_object['variable'], not for weather_object.temp or weather_object['temp'] if 'temp' is assigned to variable. Commented Dec 3, 2021 at 18:18

1 Answer 1

1

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.humiditys 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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.