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

Django遍历模型生成各城市天气信息仅返回首条数据问题排查

问题描述

遍历Django模型为每个城市生成对应天气信息时,接口仅返回第一个城市的天气数据,未返回所有城市的对应结果。

原有代码

models.py

from django.db import models
from pytz import timezone

# Create your models here.
class city(models.Model):
    name=models.CharField(max_length=40)

    def __str__(self):
        return self.name

class weather(models.Model):
    City=models.ForeignKey(city, null=True, on_delete=models.CASCADE)
    country=models.CharField(max_length=40)
    timezone=models.CharField(max_length=40)
    temperature=models.FloatField()
    humidity=models.FloatField()
    status=models.CharField(max_length=40)

    def __str__(self):
        return self.country

serializers.py

from rest_framework import serializers
from .models import weather,city

class CitySerializers(serializers.ModelSerializer):
    class Meta:
        model=city
        fields='__all__'

class WeatherSerializers(serializers.ModelSerializer):
    class Meta:
        model=weather
        fields='__all__'

views.py

from django.shortcuts import render
import requests
from .models import weather,city
from .serializers import WeatherSerializers
from rest_framework.decorators import api_view
from rest_framework.response import Response
from geopy.geocoders import Nominatim

# Create your views here.
@api_view(['GET'])
def weatherinfo(request):
    Cit=city.objects.all()
    geolocator=Nominatim(user_agent="XXXXXXXX")
    key= 'XXXXXXXXXXX'
    for obj in Cit:
        #cit=city.objects.get(city,id=obj)
        location=geolocator.geocode(obj)
        coordinates=(location.latitude,location.longitude)
        lat=coordinates[0]
        long=coordinates[1]
        url='https://api.openweathermap.org/data/2.5/weather?lat={}&lon={}&appid={}'.format(lat,long,key)
        city_weather=requests.get(url).json()

        weather_data=weather.objects.create(
        City=obj,
        country=city_weather['sys']['country'],
        timezone=city_weather['timezone'],
        temperature=city_weather["main"]["temp_max"], 
        humidity=city_weather["main"]["humidity"],
        status=city_weather["weather"][0]["description"],
        )

        serializer=WeatherSerializers(weather_data, many=False)
        return Response(serializer.data)
问题原因

return Response(serializer.data)写在了for循环内部:

  • 循环处理完第一个城市后就直接触发返回,视图函数立刻终止运行
  • 剩余城市的遍历、天气接口请求、数据入库逻辑完全不会执行,因此只会返回第一个城市的天气数据
修复方案

调整代码结构:

  1. 将返回逻辑移到循环外部
  2. 循环内仅完成所有城市的天气拉取、数据存储,把生成的天气对象统一存入列表
  3. 所有城市处理完成后,对整个天气列表做序列化,一次性返回结果

修复后的views.py代码:

from django.shortcuts import render
import requests
from .models import weather,city
from .serializers import WeatherSerializers
from rest_framework.decorators import api_view
from rest_framework.response import Response
from geopy.geocoders import Nominatim

# Create your views here.
@api_view(['GET'])
def weatherinfo(request):
    city_list = city.objects.all()
    geolocator = Nominatim(user_agent="XXXXXXXX")
    key = 'XXXXXXXXXXX'
    weather_result = []
    for obj in city_list:
        # 显式传入name字段做地理编码,避免依赖__str__方法带来的不确定性
        location = geolocator.geocode(obj.name)
        lat, long = location.latitude, location.longitude
        url = 'https://api.openweathermap.org/data/2.5/weather?lat={}&lon={}&appid={}'.format(lat, long, key)
        city_weather = requests.get(url).json()

        weather_data = weather.objects.create(
            City=obj,
            country=city_weather['sys']['country'],
            timezone=city_weather['timezone'],
            temperature=city_weather["main"]["temp_max"], 
            humidity=city_weather["main"]["humidity"],
            status=city_weather["weather"][0]["description"],
        )
        weather_result.append(weather_data)
    # 序列化列表时需要设置many=True
    serializer = WeatherSerializers(weather_result, many=True)
    return Response(serializer.data)

补充说明:当前逻辑每次调用接口都会为每个城市新增一条天气记录,如果需要更新已有城市的最新天气而非重复生成冗余数据,可以将weather.objects.create替换为weather.objects.update_or_create,以关联的City字段为查询条件更新对应字段即可。

内容的提问来源于stack exchange,提问作者Christopher Ifeoluwa Oni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:54:28