Django выполняет итерацию по словарю и рендеринг в шаблон
Этот код дает мне вывод, который мне нужен на терминале, но когда я пытаюсь вывести его в шаблоне, он дает мне только последний результат. Я прочитал несколько других ответов, но ничего не помогло мне понять, где ошибка. Спасибо.
def forecast(request):
if request.method == 'POST':
city = urllib.parse.quote_plus(request.POST['city'])
source = urllib.request.urlopen('http://api.openweathermap.org/data/2.5/forecast?q='+ city +'&units=metric&appid=ab3d24d85590d1d71fd413f0bcac6611').read()
list_of_data = json.loads(source)
pprint.pprint(list_of_data)
forecast_data = {}
for each in list_of_data['list']:
forecast_data['wind_speed'] = each["wind"]['speed']
forecast_data['wind_gust'] = each["wind"]['gust']
forecast_data['wind_deg'] = each["wind"]['deg']
forecast_data["coordinate"] = str(list_of_data['city']['coord']['lon']) + ', ' + str(list_of_data['city']['coord']['lat'])
forecast_data["name"] = list_of_data["city"]["name"]
forecast_data["dt_txt"] = each["dt_txt"]
# uncomment for see the result in the terminal
print(forecast_data)
fore = {'forecast_data':forecast_data}
else:
list_of_data = []
fore = {}
return render(request, "WindApp/forecast.html",fore)
а это HTML-часть:
<div class="row">
{% for x,y in forecast_data.items %}
<div class="col d-flex justify-content-center" ">
<div id="output" class=" card text-black bg-light mb-6">
<div id="form" class=" card-body">
<h4><span class="badge badge-primary">City:</span> {{forecast_data.name}}</h4>
<h4><span class="badge badge-primary">Coordinate:</span> {{forecast_data.coordinate}}</h4>
<h4><span class="badge badge-primary">Day/Time:</span> {{forecast_data.dt_txt}}</h4>
<h4><span class="badge badge-primary">Wind Speed: </span> {{forecast_data.wind_speed}} Kt</h4>
<h4><span class="badge badge-primary">Wind Gust : </span> {{forecast_data.wind_gust}} Kt <img src="{% static 'img/wind.png' %}" width="64" height="64" alt="wind"></h4>
<h4><span class="badge badge-primary">Wind direction : </span> {{forecast_data.wind_deg}} <img src="{% static 'img/cardinal.png' %}" width="64" height="64" alt="dir"></h4>
</div>
{% endfor %}
Запишите пользовательский фильтр в каталог templatetags
from django import template
register = template.Library()
@register.filter
def get_list(querydict, item):
return querydict.getlist(item)
затем импортируйте его в шаблон и используйте следующим образом
{% load get get_list range %}
{% for x,y in forecast_data|get_list:"items" %}
Причина: если у вас есть элементы в контексте, то есть не в forecast_data, Jinja может понять это, но если у вас есть вложенный объект, то есть тип списка (в вашем случае элементы) в каком-то другом объекте, Jinja не может получить доступ к списку
Вы выполняете итерацию по списку прогнозов, но перезаписываете один словарь последним, который видите в цикле.
Вы хотите накапливать результаты разбора в списке словарей, например:
all_forecasts = []
for each in list_of_data['list']:
forecast = {}
forecast['wind_speed'] = each["wind"]['speed']
# ... etc .. all other fields
all_forecasts.append(forecast)
fore = {'forecast_data': all_forecasts}
Позже, в шаблоне, вам нужно будет перебрать forecast_data
и вывести строку для каждого из них:
{% for forecast in forecast_data %}
<div class="row">
<div><span>City:</span><span>{% forecast.city %}</span></div>
<!-- etc the other fields -->
</div>
{% endfor %}