You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django集成OpenWeather API时循环显示图标异常问题排查

问题描述

我正在开发基于OpenWeather API的天气应用,想要用自定义图标集替换API默认的PNG图标。已参照OpenWeather天气编码规则编写匹配逻辑,当编码为'01d'等时替换为自定义图标地址,但循环遍历添加的城市时,总是显示最后一个图标(如'50n'对应的图标),而非对应城市的正确图标。以下是views.py中的代码:

def weather(request):
    
    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=metric&appid=<MYAPPKEY>'
   
    cities = City.objects.all()
    
    weather_data = []
    for city in cities:
    
        city_weather = requests.get(url.format(city)).json()
            
        weather = {
            'city' : city,
            'temperature' : city_weather['main']['temp'],
            'description' : city_weather['weather'][0]['description'],
            'icon' : city_weather['weather'][0]['icon'],
        }
    
        icon = weather['icon']
        
        if icon == '01d':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/01d.svg'
        elif icon == '01n':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/01n.svg'
        elif icon == '02d':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/02d.svg'
        elif icon == '02n':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/02n.svg'
        elif icon == '03d':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/03d.svg'
        elif icon == '03n':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/03n.svg'
        elif icon == '04d':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/04d.svg'
        elif icon == '04n':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/04n.svg'
        elif icon == '09d':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/09d.svg'
        elif icon == '09n':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/09n.svg'
        elif icon == '10d':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/10d.svg'
        elif icon == '10n':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/10n.svg'
        elif icon == '11d':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/11d.svg'
        elif icon == '11n':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/11n.svg'
        elif icon == '13d':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/13d.svg'
        elif icon == '13n':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/13n.svg'
        elif icon == '50d':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/50d.svg'
        elif icon == '50n':
            icon = 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/50n.svg'    
    
        weather_data.append(weather)

    
    context = {'weather_data' : weather_data, 'icon': icon}
    
    return render(request, 'weather/weather.html', context)
问题分析与解决方案

核心错误

  1. 未更新对应城市的图标字段:你仅将weather['icon']赋值给变量icon并修改,但从未把替换后的图标地址存回weather字典,导致weather_data里的城市对象仍保留API返回的原始编码。
  2. 上下文传递错误:context中单独传递的icon变量,在循环结束后只会保留最后一次循环的结果,模板若误用这个全局变量,就会出现所有城市显示同一图标的问题。

修正步骤

步骤1:更新weather字典的icon字段

在修改完icon变量后,将其赋值回weather字典:

# 替换完图标地址后添加此行
weather['icon'] = icon

步骤2:移除全局icon变量

每个城市的图标已包含在weather_data的元素中,无需单独传递全局icon,修改上下文:

context = {'weather_data': weather_data}

代码优化建议

用字典映射替代冗余的if-elif判断,提升代码可读性和维护性:

def weather(request):
    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=metric&appid=<MYAPPKEY>'
    cities = City.objects.all()
    
    # 定义图标映射字典
    icon_mapping = {
        '01d': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/01d.svg',
        '01n': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/01n.svg',
        '02d': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/02d.svg',
        '02n': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/02n.svg',
        '03d': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/03d.svg',
        '03n': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/03n.svg',
        '04d': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/04d.svg',
        '04n': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/04n.svg',
        '09d': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/09d.svg',
        '09n': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/09n.svg',
        '10d': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/10d.svg',
        '10n': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/10n.svg',
        '11d': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/11d.svg',
        '11n': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/11n.svg',
        '13d': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/13d.svg',
        '13n': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/13n.svg',
        '50d': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/50d.svg',
        '50n': 'https://dar-group-150-holborn.s3.eu-west-2.amazonaws.com/images/50n.svg'
    }
    
    weather_data = []
    for city in cities:
        city_weather = requests.get(url.format(city)).json()
        original_icon = city_weather['weather'][0]['icon']
        # 若找不到对应映射,保留原始编码(可选)
        custom_icon = icon_mapping.get(original_icon, original_icon)
        
        weather = {
            'city': city,
            'temperature': city_weather['main']['temp'],
            'description': city_weather['weather'][0]['description'],
            'icon': custom_icon
        }
        weather_data.append(weather)
    
    context = {'weather_data': weather_data}
    return render(request, 'weather/weather.html', context)

模板使用示例

确保模板遍历weather_data,取出每个城市的专属图标:

{% for item in weather_data %}
    <div class="city-card">
        <h3>{{ item.city }}</h3>
        <p>{{ item.temperature }}°C</p>
        <p>{{ item.description }}</p>
        <img src="{{ item.icon }}" alt="weather icon">
    </div>
{% endfor %}

内容的提问来源于stack exchange,提问作者Who Me Dunno Mate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 17:31:10