Django多日期表单、模型与OpenWeatherMap历史API的关联实现方法咨询
关联前端表单、后端模型与OpenWeatherMap API的完整流程
先说明下,从你的models.py写法来看,应该是用Django框架对吧?那下面我就基于Django,一步步帮你把前端表单、后端存储和API调用这几块串起来:
1. 前端表单:原生HTML或Django表单类都能用
你现在的原生HTML表单完全可以直接用,但如果想贴合Django的开发规范、减少冗余代码,建议写个表单类更省心:
# 在你的app下新建forms.py from django import forms class DateRangeForm(forms.Form): fromdate = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'})) todate = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
然后在模板里渲染它(记得加CSRF令牌,不然Django会拦截请求):
<form method="post" action="{% url 'date_submit' %}"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="Submit"/> </form>
要是你不想改原生HTML,那就在原代码里加上{% csrf_token %},确保表单能正常提交。
2. 后端视图:接收表单、转时间戳、调API、存数据
这是核心环节,我们要把前端传的日期转成OpenWeatherMap API需要的Unix时间戳,调用API后把数据存到你的模型里:
# views.py import requests from datetime import datetime from django.shortcuts import render from .models import MyDatesInput from .forms import DateRangeForm # 用表单类就导入,不用的话直接取request.POST数据 def date_submit_view(request): if request.method == 'POST': # 两种方式:用表单类做验证,或者直接读取POST数据 form = DateRangeForm(request.POST) if form.is_valid(): from_date = form.cleaned_data['fromdate'] to_date = form.cleaned_data['todate'] # 不用表单类的话可以这么写: # from_date = datetime.strptime(request.POST.get('fromdate'), '%Y-%m-%d').date() # to_date = datetime.strptime(request.POST.get('todate'), '%Y-%m-%d').date() # 转成API需要的秒级Unix时间戳,结束日期加86399秒(一天的秒数),确保覆盖整天数据 start_ts = int(from_date.timestamp()) end_ts = int(to_date.timestamp()) + 86399 # 调用OpenWeatherMap历史API api_key = "你的API密钥" lat = "目标纬度" # 可以改成让用户在表单里输入,或者固定某个值 lon = "目标经度" api_url = f"http://history.openweathermap.org/data/2.5/history/city?lat={lat}&lon={lon}&type=hour&start={start_ts}&end={end_ts}&appid={api_key}" response = requests.get(api_url) if response.status_code == 200: weather_data = response.json() # 从API返回结果中提取时间数据(API返回的list里每个entry的dt是秒级时间戳) timestamp_list = [entry['dt'] for entry in weather_data.get('list', [])] # 转成datetime对象,适配模型的DateTimeField数组 datetime_list = [datetime.fromtimestamp(ts) for ts in timestamp_list] # 把数据存到模型里 MyDatesInput.objects.create(dates=datetime_list) # 返回成功提示页面 return render(request, 'success.html', {'message': '数据已成功获取并存储'}) else: return render(request, 'error.html', {'message': f'API请求失败,状态码:{response.status_code}'}) else: form = DateRangeForm() return render(request, 'date_form.html', {'form': form})
3. 模型的小提醒:ArrayField是PostgreSQL专属
你用的ArrayField只有PostgreSQL数据库支持,如果你的项目用的是SQLite或MySQL,建议换成JSONField,兼容性更好:
# models.py from django.db import models class MyDatesInput(models.Model): # 替换成JSONField,适配更多数据库类型 dates = models.JSONField()
存储时datetime对象会被序列化成字符串,后续读取时再转换回来即可。
4. 最后配置路由
在项目的urls.py里添加对应路由,让表单能找到处理的视图:
# urls.py from django.urls import path from . import views urlpatterns = [ path('date-submit/', views.date_submit_view, name='date_submit'), ]
几个关键细节要注意:
- 时间戳转换:OpenWeatherMap的
start和end必须是秒级Unix时间戳,结束日期一定要加86399秒,不然只会拿到结束日0点的数据,覆盖不了整天的小时级记录。 - API参数:
type=hour是指定按小时返回历史数据,符合API的要求;lat和lon可以改成让用户在表单里输入,提升灵活性。 - 数据验证:用Django表单类会自动帮你验证日期格式,比直接读取POST数据更安全可靠。
内容的提问来源于stack exchange,提问作者unfamousfox
相关产品推荐
相关产品推荐

