Formularmodelle¶
AI coding agents
Use the official FastAPI skill for your installed version. Install it from your project directory:
uvx library-skills
See Develop with AI.
đ Ăbersetzung durch KI und Menschen
Diese Ăbersetzung wurde von KI erstellt, angeleitet von Menschen. đ€
Sie könnte Fehler enthalten, etwa MissverstĂ€ndnisse des ursprĂŒnglichen Sinns oder unnatĂŒrliche Formulierungen, usw. đ€
Sie können diese Ăbersetzung verbessern, indem Sie uns helfen, die KI-LLM besser anzuleiten.
Sie können Pydantic-Modelle verwenden, um Formularfelder in FastAPI zu deklarieren.
Hinweis
Um Formulare zu verwenden, installieren Sie zuerst python-multipart.
FĂŒgen Sie es zu Ihrem Projekt hinzu:
$ uv add python-multipart
Hinweis
Dies wird seit FastAPI Version 0.113.0 unterstĂŒtzt. đ€
Pydantic-Modelle fĂŒr Formulare¶
Sie mĂŒssen nur ein Pydantic-Modell mit den Feldern deklarieren, die Sie als Formularfelder erhalten möchten, und dann den Parameter als Form deklarieren:
from typing import Annotated
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class FormData(BaseModel):
username: str
password: str
@app.post("/login/")
async def login(data: Annotated[FormData, Form()]):
return data
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class FormData(BaseModel):
username: str
password: str
@app.post("/login/")
async def login(data: FormData = Form()):
return data
FastAPI wird die Daten fĂŒr jedes Feld aus den Formulardaten im Request extrahieren und Ihnen das von Ihnen definierte Pydantic-Modell ĂŒbergeben.
Deklarieren Sie fĂŒr HTML-Checkboxen boolesche Felder mit dem Defaultwert False.
Die Dokumentation testen¶
Sie können dies in der Dokumentations-UI unter /docs testen:
ZusĂ€tzliche Formularfelder verbieten¶
In einigen speziellen AnwendungsfÀllen (wahrscheinlich nicht sehr hÀufig) möchten Sie möglicherweise die Formularfelder auf nur diejenigen beschrÀnken, die im Pydantic-Modell deklariert sind. Und jegliche zusÀtzlichen Felder verbieten.
Hinweis
Dies wird seit FastAPI Version 0.114.0 unterstĂŒtzt. đ€
Sie können Pydantics Modellkonfiguration verwenden, um jegliche extra-Felder auf forbid zu setzen:
from typing import Annotated
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class FormData(BaseModel):
username: str
password: str
model_config = {"extra": "forbid"}
@app.post("/login/")
async def login(data: Annotated[FormData, Form()]):
return data
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class FormData(BaseModel):
username: str
password: str
model_config = {"extra": "forbid"}
@app.post("/login/")
async def login(data: FormData = Form()):
return data
Wenn ein Client versucht, einige zusÀtzliche Daten zu senden, erhÀlt er eine Error-Response.
Zum Beispiel, wenn der Client versucht, folgende Formularfelder zu senden:
username:Rickpassword:Portal Gunextra:Mr. Poopybutthole
Er erhÀlt eine Error-Response, die ihm mitteilt, dass das Feld extra nicht erlaubt ist:
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["body", "extra"],
"msg": "Extra inputs are not permitted",
"input": "Mr. Poopybutthole"
}
]
}
Formularmodelle kombinieren¶
Sie können mehrere Formularmodelle mit einzelnen Form-Parametern kombinieren.
from typing import Annotated
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class Profile(BaseModel):
name: str
class Preferences(BaseModel):
tags: list[str] = []
@app.post("/profiles/")
async def create_profile(
profile: Annotated[Profile, Form()],
preferences: Annotated[Preferences, Form()],
token: Annotated[str, Form()],
):
return {"profile": profile, "preferences": preferences, "token": token}
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class Profile(BaseModel):
name: str
class Preferences(BaseModel):
tags: list[str] = []
@app.post("/profiles/")
async def create_profile(
profile: Profile = Form(),
preferences: Preferences = Form(),
token: str = Form(),
):
return {"profile": profile, "preferences": preferences, "token": token}
Der Client sendet name, tags und token als Formularfelder. Jedes Modell validiert die Formularfelder unabhÀngig.
Die extra-Konfiguration jedes Modells gilt fĂŒr alle Formularfelder, einschlieĂlich der Felder und Dateien, die in anderen Parametern oder AbhĂ€ngigkeiten deklariert sind. Mit extra="forbid" wird jedes Feld auĂerhalb dieses Modells abgelehnt. Mit extra="allow" werden diese Felder als zusĂ€tzliche Felder im Modell aufgenommen.
Wenn mehrere Deklarationen denselben Formularfeldnamen verwenden, validiert jede den Wert dieses Feldes. Verwenden Sie kompatible Typen und EinschrĂ€nkungen fĂŒr gemeinsam genutzte Felder, damit das OpenAPI-Schema sie konsistent beschreiben kann.
Optionale Formularmodelle¶
Deklarieren Sie ein Formularmodell mit | None und dem Defaultwert None, um die Gruppe optional zu machen.
from typing import Annotated
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class Profile(BaseModel):
name: str
age: int
@app.post("/profiles/")
async def create_profile(
token: Annotated[str, Form()],
profile: Annotated[Profile | None, Form()] = None,
):
return {"token": token, "profile": profile}
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class Profile(BaseModel):
name: str
age: int
@app.post("/profiles/")
async def create_profile(
token: str = Form(),
profile: Profile | None = Form(default=None),
):
return {"token": token, "profile": profile}
Wenn weder name noch age gesendet wird, ist profile gleich None. Wenn eines der beiden gesendet wird, validiert FastAPI das Modell und erfordert beide Felder. Auch ein ĂŒbermittelter leerer Wert zĂ€hlt als Angabe eines Feldes.
Die Verwendung von | None ohne Defaultwert macht den Parameter weiterhin erforderlich.
ZusĂ€tzliche Felder folgen der extra-Konfiguration des Modells. Ignorierte zusĂ€tzliche Felder fĂŒhren nicht dazu, dass das Modell als vorhanden gilt.
Ein optionales Modell, das nur nicht aktivierte Checkboxen enthÀlt, wird weggelassen. Senden Sie einen Wert wie enabled=false, um es explizit anzugeben.
Optionale Unions von Formularmodellen¶
Sie können auch eine optionale Union von Modellen verwenden.
from typing import Annotated, Literal
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class Person(BaseModel):
kind: Literal["person"]
name: str
class Company(BaseModel):
kind: Literal["company"]
company_name: str
@app.post("/contacts/")
async def create_contact(
contact: Annotated[Person | Company | None, Form(discriminator="kind")] = None,
):
return contact
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from typing import Literal
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class Person(BaseModel):
kind: Literal["person"]
name: str
class Company(BaseModel):
kind: Literal["company"]
company_name: str
@app.post("/contacts/")
async def create_contact(
contact: Person | Company | None = Form(default=None, discriminator="kind"),
):
return contact
Wenn keine Formularfelder gesendet werden, ist contact gleich None. Senden Sie kind=person mit name oder kind=company mit company_name. Der Diskriminator wÀhlt aus, welches Modell validiert werden soll.
Unions von Formularmodellen kombinieren¶
Sie können Unions mit anderen Formularmodellen, einzelnen Form-Parametern und File-Parametern kombinieren. Jede Union wird unabhÀngig validiert.
from typing import Annotated, Literal
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class Person(BaseModel):
contact_type: Literal["person"]
name: str
class Company(BaseModel):
contact_type: Literal["company"]
company_name: str
class Email(BaseModel):
notification_type: Literal["email"]
email: str
class SMS(BaseModel):
notification_type: Literal["sms"]
phone: str
@app.post("/contacts/")
async def create_contact(
contact: Annotated[Person | Company, Form(discriminator="contact_type")],
token: Annotated[str, Form()],
notification: Annotated[
Email | SMS | None, Form(discriminator="notification_type")
] = None,
):
return {"contact": contact, "notification": notification, "token": token}
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from typing import Literal
from fastapi import FastAPI, Form
from pydantic import BaseModel
app = FastAPI()
class Person(BaseModel):
contact_type: Literal["person"]
name: str
class Company(BaseModel):
contact_type: Literal["company"]
company_name: str
class Email(BaseModel):
notification_type: Literal["email"]
email: str
class SMS(BaseModel):
notification_type: Literal["sms"]
phone: str
@app.post("/contacts/")
async def create_contact(
contact: Person | Company = Form(discriminator="contact_type"),
token: str = Form(),
notification: Email | SMS | None = Form(
default=None, discriminator="notification_type"
),
):
return {"contact": contact, "notification": notification, "token": token}
Senden Sie alle Felder im selben Formular. Senden Sie beispielsweise contact_type=person, name=Rick, notification_type=email, email=rick@example.com und token=secret.
Lassen Sie die Benachrichtigungsfelder weg, damit notification gleich None bleibt.
Formularmodelle und Dateien¶
Sie können ein Formularmodell auch mit Dateiparametern kombinieren.
from typing import Annotated
from fastapi import FastAPI, Form, UploadFile
from pydantic import BaseModel
app = FastAPI()
class Profile(BaseModel):
name: str
@app.post("/profiles/")
async def create_profile(profile: Annotated[Profile, Form()], avatar: UploadFile):
return {"profile": profile, "filename": avatar.filename}
đ€ Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import FastAPI, File, Form, UploadFile
from pydantic import BaseModel
app = FastAPI()
class Profile(BaseModel):
name: str
@app.post("/profiles/")
async def create_profile(profile: Profile = Form(), avatar: UploadFile = File()):
return {"profile": profile, "filename": avatar.filename}
Hier sendet der Client das Feld name und die Datei avatar mittels multipart/form-data.
Zusammenfassung¶
Sie können Pydantic-Modelle verwenden, um Formularfelder in FastAPI zu deklarieren. đ