我獨自 Django:快速打造天氣 API 服務(中篇)

更新 發佈閱讀 12 分鐘
Generating by ChatGPT-4o

Generating by ChatGPT-4o

在上一篇《我獨自 Django:快速打造天氣 API 服務(上篇)》中,我們介紹了如何串接開源天氣 API,以實現快速且即時的天氣資料查詢。這樣的方式雖然輕量又方便,但在實際專案中,需求往往不只於此。當你需要進一步進行數據分析、比對趨勢或產生圖表時,歷史資料的建立與儲存便成為不可或缺的一環。


本篇會介紹方法二 : 建立屬於自己的資料庫 。我們會先將外部 API 的天氣數據儲存下來,再透過設計 API 介面來實現歷史資料的查詢與運用。

在正式實作之前,有幾個重要的前置觀念需要先說明。首先是資料模型 (Models) 的建立。Django 框架本身提供了與資料庫互動的機制,讓我們可以透過 Model 定義資料結構,進行資料的新增、查詢、更新與刪除(CRUD)操作。

而建立 Models 有兩種常見的做法 :

  1. 直接在 Django 中定義模型,並透過 migrate 指令建立資料表 (Table) : 這種方式比較符合 Django 的設計,能完整掌控資料表的結構,如果是新專案建議使用這種方式。
  2. 從現有資料庫反向建立模型 : 也就是直接使用已存在的資料表,再透過 Django 對應的工具insepectdb產出 Model 程式碼。

第二點就是排程的設定,排程的方法有很多,這邊會使用適合 Django 的排程功能,每日去 call API 將需要的資料寫入 DB,藉此逐漸累積歷史資料。

最後就是 API 的設計結構,為了以後的維護與擴展,良好的 API 架構設計至關重要。本篇將帶領讀者一步步建立具備可讀性、可擴充性的標準 API 架構。
*部分的程式因為 blog 的編譯器會有點跑版,可以到我的 Medium 觀看更好複製的版本


我們接著回到程式,如果有跟上每個步驟,目前的資料架構會是 :

WEB-PROJECT/
backend/
config/
settings.py
urls.py
...
weather/
views.py
urls.py
django-backend/
manage.py
frontend/
.gitignore

再來到 weather/models.py 建立 Table 結構,輸入以下程式碼 :

from django.db import models

class Weather(models.Model):
city = models.CharField(max_length=100)
temperature = models.FloatField()
windspeed = models.FloatField()
time = models.DateTimeField()
def __str__(self):
return f"{self.city} - {self.time}"

class Meta:
db_table = 'weather_data' # Table 名稱

確認你的 config/settings.py 有正確設定 :

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'backend', # 資料庫名稱
'USER': 'root',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': '3306', # 設定的 port
}
}

INSTALLED_APPS = [
...
'weather', # App 名稱
]

然後在 backend/ 位置執行 :

python manage.py makemigrations
python manage.py migrate

回到 Database 看可以發現 Table 已經建立 :

migrate 結果

migrate 結果

如果沒有建立,可以嘗試兩種解法 :

  1. weather/migrations/ 內剛剛建立的 migration 刪掉,應該是 0002_xxxx.py,再重新執行一次上述的程式碼。
  2. 若還是不行,就直接到用 SQL 語法建立 :
CREATE TABLE `weather_data` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`city` VARCHAR(100) NOT NULL,
`temperature` FLOAT NOT NULL,
`windspeed` FLOAT NOT NULL,
`time` DATETIME NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

再來測試用 Django Shell 測試匯入是否成功 :

python manage.py shell

然後執行 :

from weather.models import Weather
from django.utils import timezone

# 建立一筆資料
Weather.objects.create( city="Taipei",
temperature=28.5,
windspeed=4.2,
time=timezone.now()
)

# 確認資料是否寫入成功
for w in Weather.objects.all():
print(w)

可以看到類似的資訊 Taipei-2025–05–03 03:08:13+00:00 ,也可以回到 Database 上檢查是否有這筆的資訊 :

Django 匯入測試

Django 匯入測試

至此,Django 匯入測試就完成了,未來若是有任何模型變更,再次執行 makemigrations 與 migrate 相關指令即可同步更新。


再來是透過現有的 Table 反向回去建立 Models.py 的方式,假設我們有個 Table 叫做 forecast_data :

# 可以直接至 SQL Server 上使用
CREATE TABLE `forecast_data` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`city` VARCHAR(100) NOT NULL,
`forecast_date` DATE NOT NULL,
`temperature_high` FLOAT NOT NULL,
`temperature_low` FLOAT NOT NULL,
`windspeed` FLOAT NOT NULL,
`description` VARCHAR(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

然後回到 backend/ :

python manage.py inspectdb forecast_data

你會在 terminal 上看到 Model 資訊 :

inspectdb 資訊

inspectdb 資訊

把 class 的部分複製到 weather/models.py 即可 :

from django.db import models

class Weather(models.Model):
city = models.CharField(max_length=100)
temperature = models.FloatField()
windspeed = models.FloatField()
time = models.DateTimeField()
def __str__(self):
return f"{self.city} - {self.time}"

class Meta:
db_table = 'weather_data' # Table 名稱


class ForecastData(models.Model):
id = models.BigAutoField(primary_key=True)
city = models.CharField(max_length=100)
forecast_date = models.DateField()
temperature_high = models.FloatField()
temperature_low = models.FloatField()
windspeed = models.FloatField()
description = models.CharField(max_length=255, blank=True, null=True)

class Meta:
managed = False # 告訴 Django : 這張表格不需要管理
db_table = 'forecast_data'

*特別提到 managed = False 的部分,可以把這一行刪除讓 Django 來控制這張表,重新執行一次 makemigrations 就好。


兩種方法都可以建立 Model,建立完 Model 之後,我們接著做序列化(Serialization),這是為了讓 Django 更方便的把資料轉為 JSON 格式,對於 API 的資料交換很重要。

weather/serializers.py 輸入以下程式碼 :

*若沒有 serializers.py 可自行建立。

from rest_framework import serializers
from .models import Weather

class WeatherSerializer(serializers.ModelSerializer):
class Meta:
model = Weather
fields = ['id', 'city', 'temperature', 'windspeed', 'time']

若缺少套件記得安裝 :

pip install djangorestframework

安裝完之後到 config/settings.py 添加 :

INSTALLED_APPS = [
...
'rest_framework',
...
]

以上完成 Django 與資料庫的連動。
接下來下篇《我獨自 Django:快速打造天氣 API 服務(下篇)
將會學到 :

  • 使用 Celery + Django 建立天氣資料的定時更新任務。
  • 設計符合 RESTful 原則的 API 架構。
留言
avatar-img
留言分享你的想法!
avatar-img
Alan的沙龍
0會員
12內容數
不定期技術文章、旅遊、人生見解分享
你可能也想看
Thumbnail
在小小的租屋房間裡,透過蝦皮購物平臺採購各種黏土、模型、美甲材料等創作素材,打造專屬黏土小宇宙的療癒過程。文中分享多個蝦皮挖寶地圖,並推薦蝦皮分潤計畫。
Thumbnail
在小小的租屋房間裡,透過蝦皮購物平臺採購各種黏土、模型、美甲材料等創作素材,打造專屬黏土小宇宙的療癒過程。文中分享多個蝦皮挖寶地圖,並推薦蝦皮分潤計畫。
Thumbnail
小蝸和小豬因購物習慣不同常起衝突,直到發現蝦皮分潤計畫,讓小豬的購物愛好產生價值,也讓小蝸開始欣賞另一半的興趣。想增加收入或改善伴侶間的購物觀念差異?讓蝦皮分潤計畫成為你們的神隊友吧!
Thumbnail
小蝸和小豬因購物習慣不同常起衝突,直到發現蝦皮分潤計畫,讓小豬的購物愛好產生價值,也讓小蝸開始欣賞另一半的興趣。想增加收入或改善伴侶間的購物觀念差異?讓蝦皮分潤計畫成為你們的神隊友吧!
Thumbnail
打開 jupyter notebook 寫一段 python 程式,可以完成五花八門的工作,這是玩程式最簡便的方式,其中可以獲得很多快樂,在現今這種資訊發達的時代,幾乎沒有門檻,只要願意,人人可享用。 下一步,希望程式可以隨時待命聽我吩咐,不想每次都要開電腦,啟動開發環境,只為完成一個重複性高
Thumbnail
打開 jupyter notebook 寫一段 python 程式,可以完成五花八門的工作,這是玩程式最簡便的方式,其中可以獲得很多快樂,在現今這種資訊發達的時代,幾乎沒有門檻,只要願意,人人可享用。 下一步,希望程式可以隨時待命聽我吩咐,不想每次都要開電腦,啟動開發環境,只為完成一個重複性高
Thumbnail
在前一篇我們已經成功地建立簽核表單及簽核節點並關聯回請假表單,而本篇會接著介紹如何管理簽核節點狀態並同步更新簽核表單狀態。
Thumbnail
在前一篇我們已經成功地建立簽核表單及簽核節點並關聯回請假表單,而本篇會接著介紹如何管理簽核節點狀態並同步更新簽核表單狀態。
Thumbnail
本文介紹瞭如何在後端系統開發時設計不同表單的簽核流程,包括請假表單和採購表單。以及如何動態生成簽核表單,並建立簽核節點。另外還介紹瞭如何利用繼承來簡化簽核流程的設定。
Thumbnail
本文介紹瞭如何在後端系統開發時設計不同表單的簽核流程,包括請假表單和採購表單。以及如何動態生成簽核表單,並建立簽核節點。另外還介紹瞭如何利用繼承來簡化簽核流程的設定。
Thumbnail
利用文字紀錄,明確寫下自己的採購項目......
Thumbnail
利用文字紀錄,明確寫下自己的採購項目......
Thumbnail
透過零售業的數位轉型,消費者期待獲得更多元的服務體驗。API 技術在電商、庫存管理和訂單處理等方面發揮關鍵作用,幫助企業提升效率並擴大營運範圍。API 管理平台為企業帶來高彈性、安全的 API 策略,加速數位轉型,提高企業韌性。昕力資訊的 API 管理平台為企業提供強力支持,助力產業進步。
Thumbnail
透過零售業的數位轉型,消費者期待獲得更多元的服務體驗。API 技術在電商、庫存管理和訂單處理等方面發揮關鍵作用,幫助企業提升效率並擴大營運範圍。API 管理平台為企業帶來高彈性、安全的 API 策略,加速數位轉型,提高企業韌性。昕力資訊的 API 管理平台為企業提供強力支持,助力產業進步。
Thumbnail
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
Thumbnail
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News