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)
关键说明
get()方法的作用:r.get('error')会在error字段不存在时返回None,不会抛出KeyError,是字典取值的安全方式- 双重校验:先判断
error是否存在,再判断错误码是否为1006,逻辑更严谨 - 额外字段校验:保存前检查
location和current字段,避免API返回异常格式数据时出错 - 错误消息传递:新增
err_msg变量,可在前端模板中展示错误提示,提升用户体验
内容的提问来源于stack exchange,提问作者Kabir Hossain
相关产品推荐
相关产品推荐

