【FastAPI 學習筆記 EP.3】查詢參數 (Query Parameters)

更新 發佈閱讀 11 分鐘

這篇文章將教你如何在 FastAPI 中宣告與使用查詢參數 (Query Parameters),讓你能實現資料過濾、搜尋與分頁等功能。

什麼是查詢參數?

查詢參數是 URL 中位於問號 ? 之後的鍵值對 (Key-Value Pairs),通常用於對資料過濾、搜尋與分頁。就像在電商網站搜尋商品,「手機」是主要路徑,而「搜尋 samsung」、「只顯示有貨」就是透過查詢參數來控制的。

查詢參數基礎概念

1. 宣告查詢參數

在 FastAPI 中,只要函式參數沒有出現在路徑字串裡,預設就會被當成查詢參數處理。

from fastapi import FastAPI

app = FastAPI()

inventory = [
    {"name": "Keyboard"},
    {"name": "Mouse"},
    {"name": "Monitor"},
    {"name": "Headset"},
]

# 範例 URL:http://127.0.0.1:8000/inventory?offset=0&limit=2
@app.get("/inventory")
def list_inventory(offset: int = 0, limit: int = 10):
    return inventory[offset : offset + limit]

在此範例中,定義了 offsetlimit 兩個整數型別的查詢參數,如果使用者未提供參數,就會自動使用 010 作為預設值。

2. 設定預設值

透過為參數指定一個值,你可以將其設為非必填,當使用者在請求 URL 中省略該參數,程式會自動使用你設定的預設值,這對於分頁功能特別實用。

from fastapi import FastAPI

app = FastAPI()

# URL 範例: http://127.0.0.1:8000/users/ 或 http://127.0.0.1:8000/users/?q=admin
@app.get("/users/")
async def read_users(q: str = "guest"):
    # 如果 URL 沒有帶 ?q=...,q 的值就會是 "guest"
    return {"user_type": q}

3. 選填參數

如果參數不是必填且沒有具體的預設值,可以把型別標註成 None,並給它預設值 None

from fastapi import FastAPI

app = FastAPI()

# 範例 URL:http://127.0.0.1:8000/orders/123?note=urgent
@app.get("/orders/{order_id}")
def read_order(order_id: str, note: str | None = None):
    data = {"order_id": order_id}
    if note is not None:
        data["note"] = note
    return data

這裡的 note: str | None = None 表示 note 是一個可選的字串參數,沒有帶就會是 None,不會拋出錯誤。

4. 布林值轉換

FastAPI 在處理布林查詢參數時,會幫你把常見字串自動轉成 True / False

from fastapi import FastAPI

app = FastAPI()

# 範例 URL:http://127.0.0.1:8000/articles/1?detailed=false
@app.get("/articles/{article_id}")
def read_article(article_id: int, detailed: bool = True):
    article = {"article_id": article_id}
    if detailed:
        article["content"] = "這裡會放一大段文章內容..."
    return article

當參數型別標註為 bool 時,像 true1onyes 這類值會被轉成 True,而 false0offno 則會被轉成 False

實作範例

下面示範一個帶有「最低價格過濾」、「關鍵字搜尋」以及「分頁」的產品列表 API。

from fastapi import FastAPI

app = FastAPI()

# 模擬資料庫
fake_products = [
    {"name": "iPhone 15", "price": 30000},
    {"name": "MacBook Pro", "price": 60000},
    {"name": "AirPods", "price": 5000},
    {"name": "iPad Air", "price": 20000},
    {"name": "Samsung S24", "price": 28000},
]

@app.get("/products/search")
def search_products(
    offset: int = 0,
    limit: int = 10,
    min_price: int | None = None,
    keyword: str | None = None,
):
    """
    查詢產品列表,支援分頁、價格過濾與關鍵字搜尋
    """
    # 複製一份資料以免影響原始數據
    result = fake_products.copy()

    # 1. 關鍵字搜尋(先進行篩選)
    if keyword is not None:
        keyword_lower = keyword.lower()
        result = [p for p in result if keyword_lower in p["name"].lower()]

    # 2. 價格過濾(繼續篩選)
    if min_price is not None:
        result = [p for p in result if p["price"] >= min_price]

    # 計算符合條件的總數
    total_count = len(result)

    # 3. 分頁切片
    result = result[offset : offset + limit]

    return {"data": result, "count": total_count}

這個 /products/search 路徑做了幾件事:

1.  keyword 也是選填條件,用來做名稱的模糊搜尋,沒有帶就不套用關鍵字過濾。

2.  min_price 是選填條件,用來排除價格低於指定值的商品。

3.  offsetlimit 控制回傳資料的區間,預設會從第 0 筆開始取出最多 10 筆。

常見錯誤與解決方法

1. 必填參數未傳值

如果對查詢參數沒有設定預設值,FastAPI 會把它視為必填。請求時少了這個參數,就會回傳 422 驗證錯誤。

# ❌ 錯誤寫法:q 沒有預設值,變成必填
def read_items(q: str):
    return {"q": q}

# ✅ 正確寫法:給定預設值 None (選填) 或具體值
def read_items(q: str | None = None):
    return {"q": q}

2. 弄錯路徑參數與查詢參數

只要參數沒有定義在 @app.get("/path/{param}") 的路徑字串中,它就會自動變成查詢參數。

# ❌ 錯誤觀念:以為 user_id 是路徑參數
@app.get("/users/")
def get_user(user_id: int): # 這裡 user_id 其實變成了查詢參數 ?user_id=...
    return {"user_id": user_id}


# ✅ 正確寫法:在裝飾器路徑中明確包含
@app.get("/users/{user_id}")
def get_user(user_id: int):
    return {"user_id": user_id}

3. 選填參數放到必填參數前面

沒有預設值的參數(必填)必須放在有預設值的參數(選填)前面,否則程式會拋出 SyntaxError 無法執行。

# ❌ 錯誤寫法:選填參數 (有預設值) 放在 必填參數 (沒預設值) 前面
@app.get("/items/")
def read_items(q: str | None = None, item_id: int):
    return {"item_id": item_id, "q": q}

# ✅ 正確寫法:必填 (item_id) 在前,選填 (q) 在後
@app.get("/items/")
def read_items(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

結語

查詢參數是靈活構建 API 的方式,能有效處理資料的篩選與呈現方式。請善用型別提示 (int, str, float) 來確保資料正確性,並正確區分「必填」與「選填」的預設值邏輯。

留言
avatar-img
梧笙 WuSheng 的沙龍
65會員
17內容數
⛰️ 梧笙,意即「吾生」,我是一個平凡的理工宅男。 生活離不開 Code 與 Game,這裡主要紀錄與分享: 📖 學習筆記|紀錄我學習過的電腦技能與知識。 💻 科技新知|整理實用工具與科技領域的資訊。 🎮 電玩娛樂|聊聊遊戲動漫與實況直播的話題。 目前更新頻率不固定,有興趣歡迎追蹤。
你可能也想看
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但我們除了能開發出應用之外, 也要設計的更人性化一點, API最重要的就是路由了
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但我們除了能開發出應用之外, 也要設計的更人性化一點, API最重要的就是路由了
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但開發出來之後, 我們會希望開放給一般使用者使用, 而一般使用者較能夠操作的媒介
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但開發出來之後, 我們會希望開放給一般使用者使用, 而一般使用者較能夠操作的媒介
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
當我們在開發一個AI應用服務時, 常常會需要載入大模型, But… 我們總不可能每一次的請求就載入一次模型吧! 這樣太沒有效率了, 也非常的浪費資源, 因此我們通常會希望應用程式啟動時就能夠載入模型, 之後每一次的請求只要讓模型進行運算即可, 那麼在FastAPI的框架中究竟要如何使用呢? 首
Thumbnail
當我們在開發一個AI應用服務時, 常常會需要載入大模型, But… 我們總不可能每一次的請求就載入一次模型吧! 這樣太沒有效率了, 也非常的浪費資源, 因此我們通常會希望應用程式啟動時就能夠載入模型, 之後每一次的請求只要讓模型進行運算即可, 那麼在FastAPI的框架中究竟要如何使用呢? 首
Thumbnail
關於FastAPI這個框架為什麼有什麼樣的優勢, 為什麼會這麼熱門? 歡迎參考「【Python 技術選型】如何選出適合的API框架呢?」。 站在巨人的肩膀上 FastAPI主要基於以下兩個重要的元件組成, Starlette與Pydantic, 就讓我們來看看兩者的關係吧! 安裝 pip
Thumbnail
關於FastAPI這個框架為什麼有什麼樣的優勢, 為什麼會這麼熱門? 歡迎參考「【Python 技術選型】如何選出適合的API框架呢?」。 站在巨人的肩膀上 FastAPI主要基於以下兩個重要的元件組成, Starlette與Pydantic, 就讓我們來看看兩者的關係吧! 安裝 pip
Thumbnail
API是我們與其他系統介接的標準化規格, 那一份好的規格勢必要能夠達到引導與驗證的作用, 避免對方介接錯誤, 引發後續的災難性損失, 因此這一章節就是要教我們如何定義每個API的欄位怎麼填? 資料型態是什麼? 以及如何生成API文件。 我們在「【🔒 Python API框架篇 - Fas
Thumbnail
API是我們與其他系統介接的標準化規格, 那一份好的規格勢必要能夠達到引導與驗證的作用, 避免對方介接錯誤, 引發後續的災難性損失, 因此這一章節就是要教我們如何定義每個API的欄位怎麼填? 資料型態是什麼? 以及如何生成API文件。 我們在「【🔒 Python API框架篇 - Fas
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有分享 FastAPI 這套API框架, 那麼當我們想要在應用程式剛執行時就註冊一些事件或者共享GPU運算模型、變數…等,當整個應用程式關閉時也進行釋放作業, 這樣的一個週期循環就是所謂的生命週期, 而在FastAPI這
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有分享 FastAPI 這套API框架, 那麼當我們想要在應用程式剛執行時就註冊一些事件或者共享GPU運算模型、變數…等,當整個應用程式關閉時也進行釋放作業, 這樣的一個週期循環就是所謂的生命週期, 而在FastAPI這
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
要如何使用unicorn啟動多個FastAPI服務, 歡迎參考我們的「【💊 Python的解憂錦囊 - FastAPI】如何啟動多個Workers」。 當我們試著設計帶入模組化時… 我們在「【💊 Python的解憂錦囊 - FastAPI】使用 lifespan 來共享資料與管理生命週期
Thumbnail
要如何使用unicorn啟動多個FastAPI服務, 歡迎參考我們的「【💊 Python的解憂錦囊 - FastAPI】如何啟動多個Workers」。 當我們試著設計帶入模組化時… 我們在「【💊 Python的解憂錦囊 - FastAPI】使用 lifespan 來共享資料與管理生命週期
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有說明如何使用uvicorn來啟動FastAPI服務, 假設今天我們的API是一個CPU密集型的運算服務時, 通常我們會希望開啟多個行程來幫忙處理, 那麼大致上的撰寫方式會像這樣: app = FastAPI( ti
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有說明如何使用uvicorn來啟動FastAPI服務, 假設今天我們的API是一個CPU密集型的運算服務時, 通常我們會希望開啟多個行程來幫忙處理, 那麼大致上的撰寫方式會像這樣: app = FastAPI( ti
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News