FastAPI Pydantic

6 Kernkonzepte
Die wichtigsten Pydantic-Konzepte für Datenvalidierung & Serialisierung in FastAPI: BaseModel · Field · Validatoren · Nested Models · Union Types · Serialisierung Pydantic ist das Herz von FastAPI für Datenvalidierung und Serialisierung. Diese Cheatsheet fasst die wichtigsten Konzepte für die Definition von Modellen, Validierungsregeln und Typen zusammen.

BaseModel – Grundlegende Modelle

class Model(BaseModel): field: type
from pydantic import BaseModel class User(BaseModel): name: str age: int email: str = "default@example.com"

BaseModel ist die Basisklasse für alle Pydantic-Modelle. Sie definiert die Struktur und Typen von Daten – mit automatischer Validierung und Typkonvertierung.

Beispiele
# Einfaches Benutzermodell
class User(BaseModel):
id: int
name: str
is_active: bool = True
tags: list[str] = []
# Modell mit Optional
from typing import Optional
class UserUpdate(BaseModel):
name: Optional[str] = None
email: Optional[str] = None
# Modell mit Alias (für JSON-Felder)
class Product(BaseModel):
name: str
price: float
category: str = Field(alias="category_name")
# Verwendung
user = User(id=1, name="Anna")
print(user.is_active) # True
print(user.dict()) # {'id': 1, 'name': 'Anna', 'is_active': True, 'tags': []}
Tipp: Nutzen Sie Optional für optionale Felder und Field(alias=...) für JSON-Feldnamen, die von Python-Namen abweichen.

Field & Constraints – Validierungsregeln

Field(..., min_length=3, ge=0, ...)
from pydantic import Field class Item(BaseModel): name: str = Field(..., min_length=2, max_length=50) price: float = Field(..., gt=0) quantity: int = Field(1, ge=0, le=100)

Field definiert Validierungsregeln für einzelne Felder – wie Mindest-/Maximallänge, Zahlenbereiche und reguläre Ausdrücke.

Wichtige Field-Parameter

Parameter Beschreibung Beispiel
... Erforderliches Feld Field(...)
default Standardwert Field(0)
min_length Mindestlänge (Strings) Field(..., min_length=2)
max_length Maximallänge (Strings) Field(..., max_length=50)
gt Größer als Field(..., gt=0)
ge Größer oder gleich Field(..., ge=0)
lt Kleiner als Field(..., lt=100)
le Kleiner oder gleich Field(..., le=100)
regex Regulärer Ausdruck Field(..., regex=r'^[a-z]+$')
alias Alternativer Feldname (JSON) Field(..., alias='user_name')
Beispiele
# Produkt-Modell mit Constraints
class Product(BaseModel):
sku: str = Field(..., min_length=3, max_length=20, regex=r'^[A-Z0-9-]+$')
name: str = Field(..., min_length=2, max_length=100)
price: float = Field(..., gt=0, le=9999.99)
stock: int = Field(0, ge=0)
description: Optional[str] = Field(None, max_length=1000)
# Benutzerdefinierte Fehlermeldungen
class Order(BaseModel):
items: list[str] = Field(..., min_items=1, description="Mindestens ein Artikel erforderlich")
Tipp: Verwenden Sie Field(..., description="...") für die OpenAPI-Dokumentation – die Beschreibung erscheint automatisch in der API-Dokumentation.

Validatoren – Benutzerdefinierte Validierung

@validator · @field_validator · @model_validator
from pydantic import validator @validator('name') def validate_name(cls, v): if not v.isalpha(): raise ValueError('Nur Buchstaben erlaubt') return v.title()

Validatoren ermöglichen benutzerdefinierte Validierungslogik für einzelne Felder oder das gesamte Modell. @validator (Pydantic V1) oder @field_validator (Pydantic V2).

Beispiele
# Pydantic V1 (FastAPI aktuell meist V2)
from pydantic import validator
class User(BaseModel):
name: str
email: str
password: str
password_confirm: str
# Feld-Validator
@validator('email')
def validate_email(cls, v):
if '@' not in v:
raise ValueError('Ungültige E-Mail-Adresse')
return v
# Cross-Field-Validator
@validator('password_confirm')
def passwords_match(cls, v, values):
if 'password' in values and v != values['password']:
raise ValueError('Passwörter stimmen nicht überein')
return v
# Pydantic V2 (neuere Syntax)
# from pydantic import field_validator, model_validator
# @field_validator('field')
# @model_validator(mode='after')
Tipp: Für Pydantic V2 (FastAPI 0.100+) verwenden Sie @field_validator und @model_validator. Die V1-Syntax (@validator) funktioniert weiterhin, wird aber in Zukunft entfernt.

Nested Models – Verschachtelte Strukturen

Model mit Untermodellen · list[Model]
class Address(BaseModel): street: str city: str class User(BaseModel): name: str address: Address orders: list[Order] = []

Nested Models ermöglichen die Abbildung komplexer, verschachtelter Datenstrukturen – ein Modell kann andere Modelle oder Listen von Modellen enthalten.

Beispiele
# Adresse als Untermodell
class Address(BaseModel):
street: str = Field(..., min_length=3)
city: str
zip_code: str = Field(..., regex=r'^\d{5}$')
country: str = "DE"
# Order als Untermodell
class Order(BaseModel):
order_id: int
total: float = Field(..., gt=0)
# Benutzer mit Adresse und Bestellungen
class User(BaseModel):
id: int
name: str
address: Address
orders: list[Order] = []
# Verwendung
user_data = {
"id": 1,
"name": "Anna",
"address": {"street": "Hauptstr. 1", "city": "Berlin", "zip_code": "10115"}
"orders": [{"order_id": 100, "total": 29.99}]
}
user = User(**user_data)
Tipp: Verschachtelte Modelle werden automatisch validiert – FastAPI prüft rekursiv alle Untermodelle. Verwenden Sie Optional für optionale Untermodelle.

Union Types – Mehrere Typen erlauben

Union · Optional · Any · Literal
from typing import Union, Optional class Config(BaseModel): value: Union[str, int, bool] optional: Optional[str] = None status: Literal['active', 'inactive']

Union Types erlauben es, dass ein Feld mehrere verschiedene Typen annehmen kann. Optional ist eine Kurzform für Union[T, None].

Beispiele
from typing import Union, Optional, Literal
# Feld kann String, Integer oder Boolean sein
class FlexibleField(BaseModel):
data: Union[str, int, bool]
# Literal: Nur bestimmte Werte erlaubt
class OrderStatus(BaseModel):
status: Literal['pending', 'shipped', 'delivered', 'cancelled']
# Any: Jeder Typ (Vorsicht, deaktiviert Typ-Prüfung)
class AnyField(BaseModel):
anything: Any
# Verwendung in FastAPI
@app.post("/config")
async def set_config(config: FlexibleField):
return {"type": type(config.data).__name__, "value": config.data}
Tipp: Nutzen Sie Literal für Enums mit festen Werten – das verbessert die Typsicherheit und erscheint in der OpenAPI-Dokumentation als Dropdown.

Serialisierung – dict(), json(), Config

model_dump() · model_dump_json() · Config
class User(BaseModel): name: str password: str age: int class Config: exclude = {'password'} json_encoders = {datetime: lambda v: v.isoformat()}

Serialisierung steuert, wie Modelle in Dictionaries oder JSON konvertiert werden – mit Optionen zum Ausschließen von Feldern, Umbenennung und Formatierung.

Beispiele
from datetime import datetime
class User(BaseModel):
id: int
name: str
password_hash: str
created_at: datetime
class Config:
# Felder ausschließen
exclude = {'password_hash'}
# JSON-Encoder für datetime
json_encoders = {datetime: lambda v: v.isoformat()}
# Feldnamen in JSON umbenennen
alias_generator = lambda field: field.upper()
populate_by_name = True
# Serialisierung mit model_dump()
user = User(id=1, name="Anna", password_hash="hash", created_at=datetime.now())
# Alle Felder (ohne password_hash)
print(user.model_dump())
# Nur bestimmte Felder
print(user.model_dump(include={'id', 'name'}))
# JSON-String
print(user.model_dump_json(indent=2))
# Pydantic V1: dict() und json()
# user.dict()
# user.json()
Tipp: Für FastAPI verwenden Sie model_dump() und model_dump_json() (Pydantic V2). Bei älteren Versionen (V1) sind es dict() und json().

Pydantic im Überblick

BaseModel Modellbasis
class User(BaseModel)
Field Validierungsregeln
min_length, gt, regex
@validator Benutzerdefinierte Validierung
Cross-Field, komplexe Logik
Nested Verschachtelte Modelle
list[Model], Model in Model
Union Mehrere Typen
Union[str, int], Optional
model_dump Serialisierung
dict(), json()

Quick Summary

BaseModel
Modellbasis
Field
Validierungsregeln
@validator
Benutzerdef. Validierung
Nested
Verschachtelte Modelle
Union
Mehrere Typen
model_dump
Serialisierung
class User(BaseModel): name: str · Field(..., min_length=3) · user.model_dump()