Моделҳои Pydantic
Чаро моделҳо лозиманд
Ҳангоми сохтани сабт муштарӣ якбора чанд қимат мефиристад: ном, миқдор ва парчам. Дастӣ санҷидани ҳар кадом душвор аст: сатри холиро фаромӯш кардан, навъро омехтан ё қоидаро дар як масир дигар кардан осон аст. Модели Pydantic шакли додаҳоро дар як ҷой муайян карда, шартномаи вуруди API мешавад.
Танаи дархост додаҳои пас аз сарлавҳаҳои HTTP аст; дар ин ҷо JSON истифода мекунем. Модел луғати вурудро ба объекте бо майдонҳои санҷидашуда табдил медиҳад. Дар курс Pydantic 2 истифода мешавад: луғатро бо model_dump() мегирем. Ҳар мисоли поёнро алоҳида иҷро кунед.
Майдонҳо, ҳатмӣ будан ва маҳдудиятҳо
Синфи вориси BaseModel майдонҳоро тавсиф мекунад. Майдони бе қимати пешфарз ҳатмӣ аст; Field ҳудудҳо меафзояд. min_length ва max_length дарозии сатрро, ge ва le ададро бо дохил кардани ҳудудҳо маҳдуд мекунанд. Сатри ададии мувофиқ метавонад ба адад табдил ёбад: санҷиши одӣ ҳамаи табдилҳоро манъ намекунад.
from pydantic import BaseModel, Field, ValidationError
class Parcel(BaseModel):
label: str = Field(min_length=2, max_length=8)
weight: int = Field(2, ge=1, le=9)
p = Parcel(label="AB", weight="4")
print(p.model_dump())
try:
Parcel(label="A")
except ValidationError as exc:
print(exc.errors()[0]["loc"], exc.errors()[0]["type"])
Баромад:
{'label': 'AB', 'weight': 4}
('label',) string_too_short
JSON ба аргументи функсия табдил меёбад
FastAPI параметри навъи моделро аз танаи дархост мехонад. Аргументи json= дар TestClient.post JSON ва Content-Type-и мувофиқро месозад. Дар коркардкунанда майдонҳо ҳамчун атрибут дастрасанд. Вуруди нодуруст 422 мегирад ва коркардкунанда оғоз намешавад: ҳисобкунаки даъватҳо инро нишон медиҳад. status_code=201 рамзи сохтани муваффақро медиҳад.
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
class Parcel(BaseModel):
label: str = Field(min_length=2)
app = FastAPI()
calls = []
@app.post("/parcels", status_code=201)
def create(parcel: Parcel):
calls.append(parcel.label)
return parcel.model_dump()
client = TestClient(app)
r = client.post("/parcels", json={"label": "AB"})
print(r.status_code, r.json())
print(client.post("/parcels", json={}).status_code)
print(len(calls))
Баромад:
201 {'label': 'AB'}
422
1
Модели ҷудои ҷавоб
Нигоҳдории дохилӣ ва ҷавоби оммавӣ вазифаҳои гуногун доранд. response_model танҳо майдонҳои эълоншударо нигоҳ дошта, месанҷад. Дар мисол токени дохилӣ ба муштарӣ намерасад. Агар худи сервер додаҳои ба модел номувофиқ баргардонад, ин хатои татбиқи ҷавоб аст, на хатои 422-и вуруд. Схемаи ҷавоб дар /docs ҳам пайдо мешавад.
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
class ParcelOut(BaseModel):
id: int
label: str
app = FastAPI()
@app.get("/parcel", response_model=ParcelOut)
def read():
return {"id": 4, "label": "AB", "internal_token": "xyz"}
r = TestClient(app).get("/parcel")
print(r.json())
print("internal_token" in r.json())
Баромад:
{'id': 4, 'label': 'AB'}
False
Майдон фиристода шуд ё не?
Навсозии қисмиро одатан бо PATCH иҷро мекунанд. Барои он майдонҳои партофташаванда ва роҳи фарқ кардани нафиристодан аз null-и ошкор лозиманд. model_dump(exclude_unset=True) танҳо майдонҳои дар вуруд набударо хориҷ мекунад. exclude_none=True вазифаи дигар дорад: ҳамаи None-ро, ҳатто ошкоро фиристодашударо, хориҷ мекунад. Фарқро бе тағйири анбор мебинем.
from pydantic import BaseModel
class ParcelPatch(BaseModel):
label: str | None = None
urgent: bool | None = None
patch = ParcelPatch(urgent=False)
print(patch.model_dump())
print(patch.model_dump(exclude_unset=True))
explicit = ParcelPatch(label=None)
print(explicit.model_dump(exclude_unset=True))
print(explicit.model_dump(exclude_none=True))
Баромад:
{'label': None, 'urgent': False}
{'urgent': False}
{'label': None}
{}
Дар дохил чӣ рӯй медиҳад
Модел ба санҷиши пурсишнома монанд аст: аввал мавҷудияти майдонҳои ҳатмӣ ва навъҳо, сипас маҳдудиятҳо санҷида мешаванд. Пас аз санҷиши муваффақ объекти модел пайдо мешавад. FastAPI ин санҷишро аз аннотатсияи параметр сохта, баъд масирро даъват мекунад ва ҷавобашро алоҳида коркард менамояд. Модели вуруд додаҳои иҷозатшудаи муштарӣ ва модели баромад ваъдаи сервер ба муштариро тавсиф мекунад.
Қимати пешфарз ҳангоми набудани майдон истифода мешавад. Ин маънои «ҳар қимати нодурустро иваз кардан»-ро надорад: null-и ошкор навъи мувофиқ, масалан str | None, талаб мекунад. Сатри танҳо аз фосилаҳо иборат ба min_length=1 мувофиқ аст, зеро фосила ҳам аломат мебошад; меъёрсозии матнро алоҳида тарҳрезӣ кунед. Ба нигоҳ доштани майдонҳои зиёдатии вуруд такя накунед: модели одӣ онҳоро бо пешфарз нодида мегирад.
Хатоҳои маъмул ва ислоҳи онҳо
weight: intбе= 2майдонро ҳатмӣ мекунад: дархости бе он 422 мегирад. Агар нафиристодан иҷозат бошад, пешфарзи дуруст илова кунед.label: str | Noneбаnullиҷозат медиҳад, вале бе= Noneнафиристоданро иҷозат намедиҳад. Барои майдони ғайриҳатмӣ ҳам навъ ва ҳам пешфарз гузоред.return parcel.model_dumpистинод ба методро бармегардонад. Онро даъват кунед:parcel.model_dump().patch.model_dump()пешфарзҳои нафиристодаро низ дар бар мегирад. Барои PATCHexclude_unset=Trueистифода кунед; агарnull-и ошкор муҳим бошад, онро боexclude_none=Trueиваз накунед.
Ёддошт
| Амал | Восита |
|---|---|
| Тавсифи сохтор | class X(BaseModel) |
| Маҳдуд кардани майдон | Field(min_length=..., ge=...) |
| Гирифтани луғат | obj.model_dump() |
| Қабули JSON | параметри навъи модел |
| Филтр кардани ҷавоб | response_model=ModelOut |
| Гирифтани танҳо майдонҳои фиристода | model_dump(exclude_unset=True) |