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

如何通过Django读取JSON文件参数并实现天气应用功能?

Django天气应用问题解决方案

问题背景

开发Django天气应用,流程为:

  • 用户输入城市名称
  • 验证该城市是否存在于数据库中
  • 若存在,将城市坐标传入天气API并返回天气数据

当前困惑:不清楚如何获取JSON文件的参数,不确定是否通过views实现、创建新模型或使用request方法,已耗时2小时未解决。

现有代码

views.py

from django.http import HttpResponse
import requests
from datetime import datetime 
from zoneinfo import ZoneInfo

def weatherdata(request):
    response = requests.get('api is here').json()
    context = {'response':response}
    return render(request,'home.html',context)

def citynamesinfo(request):
    
    response = request.FILES()
    #I don't what to do here


# input localization
# recognize specific coordenates

models.py

from django.db import models

# Create your models here.

class Weather(models.Model):
    city = models.CharField(max_length=100)
    temperature = models.DecimalField(max_digits=5,decimal_places=2)
    condition = models.CharField(max_length=100)
    
    precipitation = models.CharField(max_length=100, null=True)

    humidity = models.DecimalField(max_digits=5,decimal_places=2)

示例城市JSON结构

[{"geoname_id": "3112344", "name": "Ráfales", "ascii_name": "Rafales", "alternate_names": ["Rafales", "Rafels", "Ráfales", "Ráfels"], "feature_class": "P", "feature_code": "PPLA3", "country_code": "ES", "cou_name_en": "Spain", "country_code_2": null, "admin1_code": "52", "admin2_code": "TE", "admin3_code": "44194", "admin4_code": null, "population": 175, "elevation": null, "dem": 634, "timezone": "Europe/Madrid", "modification_date": "2012-03-04", "label_en": "Spain", "coordinates": {"lon": 0.01923, "lat": 40.8377}}]

解决方案

1. 新增City模型存储城市基础数据

要验证城市是否存在,直接操作数据库是最优方案,新增City模型来存储JSON中的城市信息:

from django.db import models

class City(models.Model):
    geoname_id = models.CharField(max_length=20, unique=True)
    name = models.CharField(max_length=100)
    ascii_name = models.CharField(max_length=100)
    country_code = models.CharField(max_length=5)
    lon = models.FloatField()
    lat = models.FloatField()
    timezone = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Weather(models.Model):
    # 关联City模型,替代原有的city字符字段
    city = models.ForeignKey(City, on_delete=models.CASCADE)
    temperature = models.DecimalField(max_digits=5, decimal_places=2)
    condition = models.CharField(max_length=100)
    precipitation = models.CharField(max_length=100, null=True)
    humidity = models.DecimalField(max_digits=5, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)

2. 将JSON数据导入数据库

执行以下代码(可在Django Shell中运行,或编写自定义管理命令),把城市JSON数据批量导入到City模型:

import json
from your_app_name.models import City

# 替换为你的JSON文件路径
with open('path/to/cities.json', 'r', encoding='utf-8') as f:
    cities_data = json.load(f)

for city in cities_data:
    # 用get_or_create避免重复导入
    City.objects.get_or_create(
        geoname_id=city['geoname_id'],
        defaults={
            'name': city['name'],
            'ascii_name': city['ascii_name'],
            'country_code': city['country_code'],
            'lon': city['coordinates']['lon'],
            'lat': city['coordinates']['lat'],
            'timezone': city['timezone']
        }
    )

3. 编写处理用户输入的视图

替换原有视图,实现用户输入、城市验证、天气API调用的完整流程:

from django.shortcuts import render
import requests
from .models import City, Weather

def home(request):
    if request.method == 'POST':
        # 获取用户输入的城市名称
        city_name = request.POST.get('city_name')
        try:
            # 忽略大小写查询城市
            city = City.objects.get(name__iexact=city_name)
            # 调用天气API,替换为你的API地址和所需参数
            weather_api_url = f"your_weather_api_endpoint?lat={city.lat}&lon={city.lon}"
            weather_response = requests.get(weather_api_url).json()
            
            # 根据天气API返回结构提取数据,以下为示例
            temperature = weather_response['main']['temp']
            condition = weather_response['weather'][0]['main']
            humidity = weather_response['main']['humidity']
            # 处理降水数据,部分API可能无此字段
            precipitation = weather_response.get('rain', {}).get('1h', '0mm')
            
            # 可选:将天气数据保存到数据库
            Weather.objects.create(
                city=city,
                temperature=temperature,
                condition=condition,
                humidity=humidity,
                precipitation=precipitation
            )
            
            # 传递数据到模板
            context = {
                'city': city.name,
                'temperature': temperature,
                'condition': condition,
                'humidity': humidity,
                'precipitation': precipitation
            }
            return render(request, 'weather_result.html', context)
        except City.DoesNotExist:
            # 城市不存在时返回提示
            return render(request, 'home.html', {'error': '该城市不存在,请重新输入'})
    # GET请求时显示输入表单
    return render(request, 'home.html')

关键说明

  • 无需使用request.FILES:你要处理的是用户输入的城市名,不是上传文件,用request.POST获取即可。
  • 必须导入render:原有weatherdata函数中未导入from django.shortcuts import render,会导致报错。
  • 数据库存储城市数据:相比每次读取JSON文件,用ORM查询数据库更高效,也符合Django的设计规范。

内容的提问来源于stack exchange,提问作者Adryan Taborda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:10:58