Django Ninja 教學 11:請求(三)查詢參數 - Query Parameters
2024 iThome 鐵人賽
上一篇我們討論了,請求 URL 中關於路徑參數的處理方式。
本文將介紹查詢參數(query parameters),這是 RESTful API 中用來傳遞過濾條件等額外資訊的重要部分。
處理查詢參數在 Django Ninja 中非常簡單直觀,我們可以透過多種方式來達成。
本文所有的程式碼變動,可參考這個 PR。
一、什麼是查詢參數?
查詢參數是 URL 中的可選參數,通常位於 path 的後方,以?key=value
的形式出現,用來傳遞額外的資訊。
例如,當我們需要過濾某位作者的文章時,URL 的 path 可能會這樣寫:
1 | /posts/?author=john |
URL 傳遞了一個查詢參數author=john
,表示我們希望過濾出由 John 撰寫的文章。
二、範例專案改動
為了更真實地介紹查詢參數,我們需要修改原先的「取得所有文章」API,加入簡單的「過濾」功能。
附帶一提,複雜的過濾功能,我們會在〈卷 23:過濾(Filtering)〉進行介紹。
修改後,當請求帶有查詢參數時,API 就能透過這些參數來限制查詢結果。如下:
1 |
|
這裡我們以「文章標題」來進行過濾。
小提醒:專案 API 目前還無法使用,一來 db 沒有資料,二來我們還沒有撰寫相關的 Schema。現階段僅作為閱讀理解上的參考。不過別擔心,我們很快會讓它 work ☺️
好,改完程式碼,接下來進行講解。
三、在 Django Ninja 中使用 Query Parameters
在 Django Ninja 中,處理查詢參數的最簡單方式,是直接將它們作為 view 函式的可選參數——透過參數預設值None
:
1 |
|
在這個例子中,title
參數被定義為一個可選的字串(None | str = None
)。
- 如果 URL 中包含
title
查詢參數,Django Ninja 會自動將其值作為引數,並傳遞給get_posts
函式。 - 如果 URL 中沒有這個查詢參數,則函式不會收到引數,此時
title
在函式中的值將會是None
——因為它有預設值。
關於這個例子,我們還需要留意以下這些地方:
- 查詢參數不需要寫在
router
裝飾器的path
參數路徑中。 - 查詢參數通常有預設值,無論是具體的值還是上述的
None
。如果缺少預設值,當查詢參數不存在時,Django Ninja 會返回 422 回應。 - 當預設值為
None
時,需留意 type hints 的寫法:None | str = None
。(相當於Optional[str] = None
) - 查詢參數和路徑參數一樣,都會依照函式的 type hints 進行型別轉換。如果沒有標記型別,那兩者的預設型別皆為
str
——因為 URL 本質都是字串。
以上寫法簡單直接,適用於大多數情況。
然而,當我們需要對查詢參數進行更複雜的驗證或限制時,就需要使用進階的技巧——Query
。
四、使用 Query 物件
當我們需要進行更詳細的控制,例如限制查詢參數的長度、範圍,或為 API 文件加上額外資訊時,可以使用Query
來設定、處理查詢參數。
必須承認,我之前開發其實也很少用到Query
,但了解它 20% 最重要的特性,肯定會很有幫助。
Query
類別介紹
透過Query
物件,我們可以對查詢參數進行更精細的定義與驗證。
事實上,如果你看過 Django Ninja 的原始碼,你會發現:它其實是一個函式。只不過會返回相同名稱的類別物件。為了解說方便,我們暫且當它是類別吧!
參考這個修改後的範例:
1 | from ninja import Query, Router |
它和原來的這個寫法幾乎是等價的:(仍有細微不同,但可以先忽略)
1 | def get_posts(request: HttpRequest, title: None | str = None): |
你可能會覺得奇怪,那我沒事幹嘛要換一個更複雜的寫法,卻沒有額外的好處?
這當然是因為,更複雜的寫法,能做的事情也更多。
限制查詢字串的長度
比如我們想要限制title
這個查詢字串,不可以太長也不可以太短。
假設要求長度在 2 到 10 個字元好了。
此時你就可以這樣寫:
1 | def get_posts( |
這個範例中,我們使用了Query
來定義title
查詢參數,並額外給予了min_length
和max_length
這兩個初始化Query
的參數設定。
這樣做可以確保title
查詢參數的長度在 2 到 10 個字元之間。
如果用戶輸入的title
不符合這個長度要求,如上一篇所述,Django Ninja 會自動返回一個狀態碼為 422 的回應,無需我們手動處理這些驗證邏輯與相關回應。
1 | // 422 Unprocessable Entity |
Query
的其他常用參數
除了min_length
和max_length
,Query
還提供了許多實用的參數,供你限制查詢條件、為 API 文件補充額外資訊,常見的有:
gt
、ge
:查詢參數的值必須大於或大於等於某個數字。lt
、le
:查詢參數的值必須小於或小於等於某個數字。example
、examples
:為 API 文件提供查詢參數的範例值,讓用戶更容易理解參數用法。
這部分我們就不示範了。
小結與下一步
查詢參數是 RESTful API 常見且重要的組成部分。Django Ninja 中,我們可以透過簡單的方式來處理查詢參數,也可以使用Query
進行更高級的驗證和控制。
了解了 Django Ninja 如何處理 URL 的相關參數後,接下來則是重頭戲。
下一步,我們將探討如何在 Django Ninja 中處理 HTTP request body,介紹如何使用 Schema 來進行資料驗證與反序列化,讓我們能夠靈活地處理複雜的請求資訊。
相關文章