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

Django项目中Weather Api城市存在性判断的KeyError问题解决

解决Django调用WeatherAPI时的KeyError问题

问题分析

你之前的两种判断逻辑都直接通过r['key']硬取字典值,当响应里没有对应字段时就会触发KeyError:

  • Code A在城市存在时,响应里没有error字段,直接取r['error']['code']会报错
  • Code B在城市不存在时,响应里没有current字段,取r['current']['condition']['code']会报错

正确的做法是先安全判断响应中是否存在目标字段,再做后续逻辑处理。

解决方案

通过字典的get()方法安全获取值,或者先判断键是否存在,就能避免KeyError。以下是修改后的核心逻辑:

核心判断逻辑

替换你原来的Code A/B代码块,改成这段安全判断:

r = requests.get(url.format(new_city)).json()

# 安全检查城市是否不存在
error_info = r.get('error')
if error_info and error_info.get('code') == 1006:
    err_msg = "City does not exist"
else:
    # 额外校验必要字段,避免异常数据存入数据库
    if 'location' in r and 'current' in r:
        form.save()
    else:
        err_msg = "API返回数据格式异常"

完整修改后的视图函数

from django.shortcuts import render
import requests
from .models import City
from .forms import CityForm

def index(request):
    url = 'http://api.weatherapi.com/v1/current.json?key=403d3701b46c42a2bac104734221012&q={}&aqi=yes'
    err_msg = ""  # 初始化错误消息,用于前端展示
    
    if request.method == 'POST':
        form = CityForm(request.POST)
        if form.is_valid():
            new_city = form.cleaned_data['name']
            existing_city_count = City.objects.filter(name=new_city).count()
            
            if existing_city_count == 0:
                r = requests.get(url.format(new_city)).json()
                
                # 安全判断城市是否不存在
                error_info = r.get('error')
                if error_info and error_info.get('code') == 1006:
                    err_msg = "City does not exist"
                else:
                    # 校验核心字段是否存在,避免无效数据入库
                    if 'location' in r and 'current' in r:
                        form.save()
                    else:
                        err_msg = "API返回数据格式异常"
            else:
                err_msg = "City Already exist in the database"
    
    form = CityForm()
    cities = City.objects.all()
    wd = []
    
    for city in cities:
        r = requests.get(url.format(city)).json()
        # 对已存储城市的天气数据也做安全校验,避免页面崩溃
        if 'location' in r and 'current' in r:
            cw = {
                'city': r['location']['name'],
                'temp': r['current']['temp_c'],
                'desc': r['current']['condition']['text'],
                'icon': r['current']['condition']['icon'],
                'code': r['current']['condition']['code'],
            }
            wd.append(cw)
        else:
            print(f"获取城市{city}的天气数据失败")
    
    context = {'cw': wd, 'addform': form, 'err_msg': err_msg}
    return render(request, 'wa/index.html', context)

关键说明

  1. get()方法的作用:r.get('error')会在error字段不存在时返回None,不会抛出KeyError,是字典取值的安全方式
  2. 双重校验:先判断error是否存在,再判断错误码是否为1006,逻辑更严谨
  3. 额外字段校验:保存前检查location和current字段,避免API返回异常格式数据时出错
  4. 错误消息传递:新增err_msg变量,可在前端模板中展示错误提示,提升用户体验

内容的提问来源于stack exchange,提问作者Kabir Hossain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:45:35