Ana içeriğe geç

Form Model'leri

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.

🌐 Yapay Zekâ ve İnsanlar Tarafından Çeviri

Bu çeviri, insanlar tarafından yönlendirilen bir yapay zekâ ile oluşturuldu. 🤝

Orijinal anlamın yanlış anlaşılması ya da kulağa doğal gelmeme gibi hatalar içerebilir. 🤖

Yapay zekâ LLM'ini daha iyi yönlendirmemize yardımcı olarak bu çeviriyi iyileştirebilirsiniz.

İngilizce sürüm

FastAPI'de form field'larını tanımlamak için Pydantic model'lerini kullanabilirsiniz.

Not

Form'ları kullanmak için önce python-multipart'ı yükleyin.

Projenize ekleyin:

$ uv add python-multipart

Not

Bu özellik FastAPI 0.113.0 sürümünden itibaren desteklenmektedir. 🤓

Form'lar için Pydantic Model'leri

Sadece, form field olarak almak istediğiniz alanlarla bir Pydantic model tanımlayın ve ardından parametreyi Form olarak bildirin:

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, request içindeki form data'dan her bir field için veriyi çıkarır ve size tanımladığınız Pydantic model'ini verir.

HTML onay kutuları için varsayılan değeri False olan boolean field'lar tanımlayın.

Dokümanları Kontrol Edin

Bunu /docs altındaki doküman arayüzünde doğrulayabilirsiniz:

Fazladan Form Field'larını Yasaklayın

Bazı özel kullanım senaryolarında (muhtemelen çok yaygın değildir), form field'larını yalnızca Pydantic model'inde tanımlananlarla sınırlamak isteyebilirsiniz. Ve fazladan gelen field'ları yasaklayabilirsiniz.

Not

Bu özellik FastAPI 0.114.0 sürümünden itibaren desteklenmektedir. 🤓

Herhangi bir extra field'ı forbid etmek için Pydantic'in model konfigürasyonunu kullanabilirsiniz:

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

Bir client fazladan veri göndermeye çalışırsa, bir error response alır.

Örneğin, client şu form field'larını göndermeye çalışırsa:

  • username: Rick
  • password: Portal Gun
  • extra: Mr. Poopybutthole

extra field'ının izinli olmadığını söyleyen bir error response alır:

{
    "detail": [
        {
            "type": "extra_forbidden",
            "loc": ["body", "extra"],
            "msg": "Extra inputs are not permitted",
            "input": "Mr. Poopybutthole"
        }
    ]
}

Form Model'lerini Birleştirin

Birden fazla form model'ini ayrı Form parametreleriyle birleştirebilirsiniz.

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}

Client, name, tags ve token değerlerini form field'ları olarak gönderir. Her model, form field'larını bağımsız olarak doğrular.

Her model'in extra konfigürasyonu, diğer parametrelerde veya bağımlılıklarda tanımlanan field'lar ve dosyalar dahil tüm form field'larına uygulanır. extra="forbid" kullanıldığında, o model'in dışındaki tüm field'lar reddedilir. extra="allow" kullanıldığında ise bu field'lar model'e ek veri olarak dahil edilir.

Birden fazla tanım aynı form field adını kullanıyorsa, her biri o field'ın değerini doğrular. OpenAPI şemasının ortak field'ları tutarlı bir şekilde tanımlayabilmesi için bu field'larda uyumlu türler ve kısıtlamalar kullanın.

İsteğe Bağlı Form Model'leri

Grubu isteğe bağlı hale getirmek için form model'ini | None ile tanımlayın ve varsayılan değerini None olarak belirleyin.

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}

Ne name ne de age gönderilirse, profile değeri None olur. İkisinden biri gönderilirse, FastAPI model'i doğrular ve her iki field'ı da zorunlu tutar. Boş bir değer gönderilmesi de field'ın sağlandığı anlamına gelir.

Varsayılan değer belirtmeden | None kullanırsanız parametre yine zorunlu olur.

Fazladan field'lar, model'in extra konfigürasyonuna göre işlenir. Yok sayılan fazladan field'lar, model'in sağlanmış sayılmasına neden olmaz.

Yalnızca işaretlenmemiş onay kutuları içeren isteğe bağlı bir model, gönderilmemiş kabul edilir. Model'i açıkça sağlamak için enabled=false gibi bir değer gönderin.

Form Model'lerinin İsteğe Bağlı Union'ları

Model'lerden oluşan isteğe bağlı bir union da kullanabilirsiniz.

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

Hiçbir form field'ı gönderilmezse, contact değeri None olur. name ile birlikte kind=person veya company_name ile birlikte kind=company gönderin. Discriminator (ayırt edici), hangi model'in doğrulanacağını seçer.

Form Model'lerinin Union'larını Birleştirin

Union'ları diğer form model'leriyle, ayrı Form parametreleriyle ve File parametreleriyle birleştirebilirsiniz. Her union bağımsız olarak doğrulanır.

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}

Tüm field'ları aynı form içinde gönderin. Örneğin, contact_type=person, name=Rick, notification_type=email, email=rick@example.com ve token=secret gönderin.

notification değerini None olarak bırakmak için bildirim field'larını göndermeyin.

Form Model'leri ve Dosyalar

Bir form model'ini dosya parametreleriyle de birleştirebilirsiniz.

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}

Burada client, name field'ını ve avatar dosyasını multipart/form-data kullanarak gönderir.

Özet

FastAPI'de form field'larını tanımlamak için Pydantic model'lerini kullanabilirsiniz. 😎