您好,登錄后才能下訂單哦!
這篇文章主要介紹“基于Pydantic封裝的通用模型在API請(qǐng)求驗(yàn)證中怎么應(yīng)用”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“基于Pydantic封裝的通用模型在API請(qǐng)求驗(yàn)證中怎么應(yīng)用”文章能幫助大家解決問題。
首先,我們定義了以下幾個(gè)基礎(chǔ)的 Pydantic 模型:
DateModel
:用于表示日期范圍,包含開始日期和結(jié)束日期。
OrderModel
:用于表示排序參數(shù),包含排序字段和排序方式(升序或降序)。
PageModel
:用于表示分頁參數(shù),包含頁碼和每頁數(shù)量。
#!/usr/bin/python3 # -*- coding: utf-8 -*- # @author: hui # @Desc: { 通用的一些Pydantic模型 } # @Date: 2023/03/30 11:57 from pydantic import BaseModel, Field, validator from typing import Optional from datetime import date class DateModel(BaseModel): """日期模型""" start_date: Optional[date] = Field(None, description="開始日期") end_date: Optional[date] = Field(None, description="結(jié)束日期") @validator("end_date", always=True) def validate_end_date(cls, end_date, values): start_date = values.get("start_date") if all([start_date, end_date]) and end_date < start_date: raise ValueError("結(jié)束日期必須大于等于開始日期") return end_date class OrderModel(BaseModel): """排序模型""" order_by: Optional[str] = Field(None, description="排序字段,逗號(hào)分隔") order_mode: Optional[str] = Field(None, description="排序方式,逗號(hào)分隔,asc升序desc降序") @validator("order_by", "order_mode", always=True) def split_comma_separated_string(cls, value): if value: return value.split(",") return value @validator("order_mode", always=True) def check_length(cls, order_mode, values): order_by = values.get("order_by") if order_by and order_mode and len(order_by) != len(order_mode): raise ValueError("order_by and order_mode must have the same length") return order_mode class PageModel(BaseModel): """分頁模型""" page: Optional[int] = Field(default=1, ge=1, description="頁碼") page_size: Optional[int] = Field(default=10, le=1000, description="每頁數(shù)量, 默認(rèn)10,最大1000")
接下來,我們通過混入(Mixin)和組合兩種不同的方式將這些基礎(chǔ)模型應(yīng)用到一個(gè)實(shí)際的 API 請(qǐng)求中。
DateOrderModelMixin
類通過多重繼承的方式繼承了 DateModel
和 OrderModel
。這種方式的優(yōu)點(diǎn)是簡(jiǎn)單易懂,可以實(shí)現(xiàn)代碼重用。然而,它也可能導(dǎo)致類層次結(jié)構(gòu)變得復(fù)雜,尤其是當(dāng)有多個(gè) Mixin 之間存在依賴關(guān)系時(shí)。
class DateOrderModelMixin(DateModel, OrderModel): """日期與排序模型Mixin""" pass
PageOrderModel
類通過組合的方式將 OrderModel
和 PageModel
作為它的屬性。在初始化方法中,我們將請(qǐng)求參數(shù)映射到這兩個(gè)模型,并調(diào)用基類的初始化方法。
組合模式的優(yōu)點(diǎn)是代碼結(jié)構(gòu)更清晰,易于維護(hù)和擴(kuò)展。但是,它可能需要編寫更多的代碼來將功能委托給組合的組件。
class PageOrderModel(BaseModel): """分頁排序模型""" order_model: OrderModel = Field(OrderModel(), description="排序模型") page_model: PageModel = Field(PageModel(), description="分頁模型") def __init__(self, **data): if "order_model" in data and "page_model" in data: order_model = data.pop("order_model", None) page_model = data.pop("page_model", None) else: # 用于直接平鋪的字典入?yún)? order_params = { "order_by": data.pop("order_by", None), "order_mode": data.pop("order_mode", None), } page_params = { "page": data.pop("page", None), "page_size": data.pop("page_size", None), } order_model = OrderModel(**order_params) page_model = PageModel(**page_params) super().__init__(order_model=order_model, page_model=page_model, **data) page_order = PageOrderModel( order_model=OrderModel(order_by="field1,field2", order_mode="asc,desc"), page_model=PageModel(page=1, page_size=10) ) >>>out order_model=OrderModel(order_by=['field1', 'field2'], order_mode=['asc', 'desc']) page_model=PageModel(page=1, page_size=10) req_params = { "order_by": "field1,field2", "order_mode": "asc,desc", "page": 1, "page_size": 10 } req_model = PageOrderModel(**req_params) >>>out order_model=OrderModel(order_by=['field1', 'field2'], order_mode=['asc', 'desc']) page_model=PageModel(page=1, page_size=10)
再來幾個(gè)業(yè)務(wù)邏輯模型繼承 DateOrderModelMixin 和 PageOrderModel 然后模擬一些請(qǐng)求參數(shù)去驗(yàn)證
讓我們創(chuàng)建兩個(gè)業(yè)務(wù)邏輯模型,一個(gè)用于查詢商品信息,另一個(gè)用于查詢訂單信息。這兩個(gè)模型分別繼承 DateOrderModelMixin
和 PageOrderModel
。
from pydantic import BaseModel, Field from typing import Optional class ProductQueryModel(DateOrderModelMixin): product_category: Optional[str] = Field(None, description="商品類別") class OrderQueryModel(PageOrderModel): customer_id: Optional[int] = Field(None, description="客戶ID") # 使用 ProductQueryModel 進(jìn)行參數(shù)驗(yàn)證 product_query_params = { "start_date": "2023-04-01", "end_date": "2023-04-30", "order_by": "price", "order_mode": "desc", "product_category": "Electronics" } product_query = ProductQueryModel(**product_query_params) >>>out order_by=['price'] order_mode=['desc'] start_date=datetime.date(2023, 4, 1) end_date=datetime.date(2023, 4, 30) product_category='Electronics' # 使用 OrderQueryModel 進(jìn)行參數(shù)驗(yàn)證 order_query_params = { "start_date": "2023-04-01", "end_date": "2023-04-30", "order_by": "order_date", "order_mode": "asc", "page": 1, "page_size": 20, "customer_id": 12345 } order_query = OrderQueryModel(**order_query_params) >>>out order_model=OrderModel(order_by=['order_date'], order_mode=['asc']) page_model=PageModel(page=1, page_size=20) customer_id=12345
這里的 ProductQueryModel
和 OrderQueryModel
分別用于處理商品查詢和訂單查詢的請(qǐng)求參數(shù)。ProductQueryModel
繼承自 DateOrderModelMixin
,因此它具有日期范圍和排序功能。OrderQueryModel
則繼承自 PageOrderModel
,具有分頁和排序功能。
通過這兩個(gè)模型,我們可以輕松地驗(yàn)證和解析傳入的請(qǐng)求參數(shù)。在上面的示例代碼中,我們分別創(chuàng)建了 product_query_params
和 order_query_params
字典來模擬請(qǐng)求參數(shù),并使用 ProductQueryModel
和 OrderQueryModel
進(jìn)行驗(yàn)證??梢钥吹?,這兩個(gè)模型成功解析了請(qǐng)求參數(shù),并對(duì)日期范圍、排序和分頁進(jìn)行了驗(yàn)證。
在處理Pydantic模型時(shí),根據(jù)具體的業(yè)務(wù)場(chǎng)景和需求來選擇組合或Mixin模式。
Mixin模式適用于簡(jiǎn)單的繼承關(guān)系,代碼簡(jiǎn)潔易懂;組合模式適用于復(fù)雜的類關(guān)系,提供更好的靈活性和擴(kuò)展性。在實(shí)際項(xiàng)目中,可以根據(jù)需求靈活選擇這兩種模式,或者根據(jù)情況將它們結(jié)合使用。
在實(shí)踐中,如果需要將多個(gè)通用功能混合到一個(gè)業(yè)務(wù)邏輯模型中,Mixin模式可能是一個(gè)更好的選擇,因?yàn)樗梢宰屛覀冚p松地將這些功能組合在一起。然而,當(dāng)我們需要對(duì)這些功能進(jìn)行更精細(xì)的控制,或者在多個(gè)業(yè)務(wù)邏輯模型之間共享某些功能時(shí),組合模式可能會(huì)更合適。
總之,在處理Pydantic模型時(shí),我們應(yīng)根據(jù)項(xiàng)目的實(shí)際需求和場(chǎng)景來權(quán)衡這兩種模式的優(yōu)缺點(diǎn),從而做出合適的選擇。這里的入?yún)⑿r?yàn)感覺使用多繼承會(huì)更簡(jiǎn)單點(diǎn),但到一些復(fù)雜的業(yè)務(wù)邏輯處理時(shí)可以使用組合模式,來做到更好的維護(hù)與擴(kuò)展。
由于 GET 請(qǐng)求的入?yún)⒉惶枚x數(shù)據(jù)結(jié)構(gòu),減少的代碼冗余就想到了多繼承來組合屬性和方法,如果使用 POST 請(qǐng)求傳遞 json 數(shù)據(jù)入?yún)⒕涂梢愿迷O(shè)計(jì)參數(shù)結(jié)構(gòu),這時(shí)使用組合的方式hui更好。
go的結(jié)構(gòu)體嵌套就有點(diǎn)像組合
type Address struct { Street string City string State string Zip string } type Person struct { Name string Age int Address Address }
通過結(jié)構(gòu)體的組合,可以方便地組合多個(gè)不同的數(shù)據(jù)結(jié)構(gòu),構(gòu)建出更加復(fù)雜的結(jié)構(gòu)體。這種組合方式可以讓代碼更加靈活和可維護(hù),同時(shí)也可以提高代碼的可讀性和可重用性。
關(guān)于“基于Pydantic封裝的通用模型在API請(qǐng)求驗(yàn)證中怎么應(yīng)用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。