【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會員
14內容數
⛰️ 梧笙,意即「吾生」,我是一個平凡的理工宅男。 生活離不開 Code 與 Game,這裡主要紀錄與分享: 📖 學習筆記|紀錄我學習過的電腦技能與知識。 💻 科技新知|整理實用工具與科技領域的資訊。 🎮 電玩娛樂|聊聊遊戲動漫與實況直播的話題。 目前更新頻率不固定,有興趣歡迎追蹤。
你可能也想看
Thumbnail
賽勒布倫尼科夫以流亡處境回望蘇聯電影導演帕拉贊諾夫的舞台作品,以十段寓言式殘篇,重新拼貼記憶、暴力與美學,並將審查、政治犯、戰爭陰影與「形式即政治」的劇場傳統推到台前。本文聚焦於《傳奇:帕拉贊諾夫的十段殘篇》的舞台美術、音樂與多重扮演策略,嘗試解析極權底下不可言說之事,將如何成為可被觀看的公共發聲。
Thumbnail
賽勒布倫尼科夫以流亡處境回望蘇聯電影導演帕拉贊諾夫的舞台作品,以十段寓言式殘篇,重新拼貼記憶、暴力與美學,並將審查、政治犯、戰爭陰影與「形式即政治」的劇場傳統推到台前。本文聚焦於《傳奇:帕拉贊諾夫的十段殘篇》的舞台美術、音樂與多重扮演策略,嘗試解析極權底下不可言說之事,將如何成為可被觀看的公共發聲。
Thumbnail
柏林劇團在 2026 北藝嚴選,再次帶來由布萊希特改編的經典劇目《三便士歌劇》(The Threepenny Opera),導演巴里・柯斯基以舞台結構與舞台調度,重新向「疏離」進行提問。本文將從觀眾慾望作為戲劇內核,藉由沉浸與疏離的辯證,解析此作如何再次照見觀眾自身的位置。
Thumbnail
柏林劇團在 2026 北藝嚴選,再次帶來由布萊希特改編的經典劇目《三便士歌劇》(The Threepenny Opera),導演巴里・柯斯基以舞台結構與舞台調度,重新向「疏離」進行提問。本文將從觀眾慾望作為戲劇內核,藉由沉浸與疏離的辯證,解析此作如何再次照見觀眾自身的位置。
Thumbnail
本文深入解析臺灣劇團「晃晃跨幅町」對易卜生經典劇作《海妲.蓋柏樂》的詮釋,從劇本歷史、聲響與舞臺設計,到演員的主體創作方法,探討此版本如何讓經典劇作在當代劇場語境下煥發新生,滿足現代觀眾的觀看慾望。
Thumbnail
本文深入解析臺灣劇團「晃晃跨幅町」對易卜生經典劇作《海妲.蓋柏樂》的詮釋,從劇本歷史、聲響與舞臺設計,到演員的主體創作方法,探討此版本如何讓經典劇作在當代劇場語境下煥發新生,滿足現代觀眾的觀看慾望。
Thumbnail
《轉轉生》為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,融合舞蹈、音樂、時尚和視覺藝術,透過身體、服裝與群舞結構,回應殖民歷史、城市經驗與祖靈記憶的交錯。本文將從服裝設計、身體語彙與「輪迴」的「誕生—死亡—重生」結構出發,分析《轉轉生》如何以當代目光,形塑去殖民視角的奈及利亞歷史。
Thumbnail
《轉轉生》為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,融合舞蹈、音樂、時尚和視覺藝術,透過身體、服裝與群舞結構,回應殖民歷史、城市經驗與祖靈記憶的交錯。本文將從服裝設計、身體語彙與「輪迴」的「誕生—死亡—重生」結構出發,分析《轉轉生》如何以當代目光,形塑去殖民視角的奈及利亞歷史。
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但開發出來之後, 我們會希望開放給一般使用者使用, 而一般使用者較能夠操作的媒介
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但開發出來之後, 我們會希望開放給一般使用者使用, 而一般使用者較能夠操作的媒介
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但我們除了能開發出應用之外, 也要設計的更人性化一點, API最重要的就是路由了
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但我們除了能開發出應用之外, 也要設計的更人性化一點, API最重要的就是路由了
Thumbnail
API是我們與其他系統介接的標準化規格, 那一份好的規格勢必要能夠達到引導與驗證的作用, 避免對方介接錯誤, 引發後續的災難性損失, 因此這一章節就是要教我們如何定義每個API的欄位怎麼填? 資料型態是什麼? 以及如何生成API文件。 我們在「【🔒 Python API框架篇 - Fas
Thumbnail
API是我們與其他系統介接的標準化規格, 那一份好的規格勢必要能夠達到引導與驗證的作用, 避免對方介接錯誤, 引發後續的災難性損失, 因此這一章節就是要教我們如何定義每個API的欄位怎麼填? 資料型態是什麼? 以及如何生成API文件。 我們在「【🔒 Python API框架篇 - Fas
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
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有分享 FastAPI 這套API框架, 那麼當我們想要在應用程式剛執行時就註冊一些事件或者共享GPU運算模型、變數…等,當整個應用程式關閉時也進行釋放作業, 這樣的一個週期循環就是所謂的生命週期, 而在FastAPI這
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有分享 FastAPI 這套API框架, 那麼當我們想要在應用程式剛執行時就註冊一些事件或者共享GPU運算模型、變數…等,當整個應用程式關閉時也進行釋放作業, 這樣的一個週期循環就是所謂的生命週期, 而在FastAPI這
Thumbnail
當我們在開發一個AI應用服務時, 常常會需要載入大模型, But… 我們總不可能每一次的請求就載入一次模型吧! 這樣太沒有效率了, 也非常的浪費資源, 因此我們通常會希望應用程式啟動時就能夠載入模型, 之後每一次的請求只要讓模型進行運算即可, 那麼在FastAPI的框架中究竟要如何使用呢? 首
Thumbnail
當我們在開發一個AI應用服務時, 常常會需要載入大模型, But… 我們總不可能每一次的請求就載入一次模型吧! 這樣太沒有效率了, 也非常的浪費資源, 因此我們通常會希望應用程式啟動時就能夠載入模型, 之後每一次的請求只要讓模型進行運算即可, 那麼在FastAPI的框架中究竟要如何使用呢? 首
Thumbnail
關於FastAPI這個框架為什麼有什麼樣的優勢, 為什麼會這麼熱門? 歡迎參考「【Python 技術選型】如何選出適合的API框架呢?」。 站在巨人的肩膀上 FastAPI主要基於以下兩個重要的元件組成, Starlette與Pydantic, 就讓我們來看看兩者的關係吧! 安裝 pip
Thumbnail
關於FastAPI這個框架為什麼有什麼樣的優勢, 為什麼會這麼熱門? 歡迎參考「【Python 技術選型】如何選出適合的API框架呢?」。 站在巨人的肩膀上 FastAPI主要基於以下兩個重要的元件組成, Starlette與Pydantic, 就讓我們來看看兩者的關係吧! 安裝 pip
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News