Skip to main content
Fields are the building blocks of Pydantic models. The Field function provides fine-grained control over field validation, serialization, and metadata.

Field Function

The Field function creates a FieldInfo object that configures field behavior:
from pydantic import BaseModel, Field

class User(BaseModel):
    id: int = Field(description='User ID')
    name: str = Field(min_length=1, max_length=100)
    email: str = Field(pattern=r'^[\w\.-]+@[\w\.-]+\.\w+$')
    age: int = Field(gt=0, le=120)

user = User(id=1, name='John', email='[email protected]', age=30)
print(user)
#> id=1 name='John' email='[email protected]' age=30

Field Parameters

Default Values

default
Any
The default value for the field
default_factory
Callable
A callable that returns the default value
from pydantic import BaseModel, Field
from datetime import datetime
from typing import List

class User(BaseModel):
    name: str
    created_at: datetime = Field(default_factory=datetime.now)
    tags: List[str] = Field(default_factory=list)

user1 = User(name='John')
user2 = User(name='Jane')

print(user1.created_at != user2.created_at)  # Different times
#> True

user1.tags.append('admin')
print(user1.tags)
#> ['admin']
print(user2.tags)  # Separate list
#> []

Validation Constraints

Numeric Constraints

gt
float | None
Value must be greater than this number
ge
float | None
Value must be greater than or equal to this number
lt
float | None
Value must be less than this number
le
float | None
Value must be less than or equal to this number
multiple_of
float | None
Value must be a multiple of this number
from pydantic import BaseModel, Field, ValidationError

class Product(BaseModel):
    price: float = Field(gt=0, le=10000)
    quantity: int = Field(ge=0, multiple_of=5)

product = Product(price=99.99, quantity=10)
print(product)
#> price=99.99 quantity=10

try:
    Product(price=-10, quantity=10)
except ValidationError as e:
    print(e)
    '''
    1 validation error for Product
    price
      Input should be greater than 0
    '''

String Constraints

min_length
int | None
Minimum string length
max_length
int | None
Maximum string length
pattern
str | Pattern | None
Regex pattern the string must match
from pydantic import BaseModel, Field, ValidationError

class User(BaseModel):
    username: str = Field(min_length=3, max_length=20)
    email: str = Field(pattern=r'^[\w\.-]+@[\w\.-]+\.\w+$')
    zipcode: str = Field(pattern=r'^\d{5}$')

user = User(
    username='john_doe',
    email='[email protected]',
    zipcode='12345'
)
print(user)

try:
    User(username='ab', email='invalid', zipcode='123')
except ValidationError as e:
    print(len(e.errors()))
    #> 3

Field Aliases

alias
str | None
Alternative name for the field (used for both validation and serialization)
validation_alias
str | AliasPath | AliasChoices | None
Alias used only during validation
serialization_alias
str | None
Alias used only during serialization
from pydantic import BaseModel, Field

class User(BaseModel):
    user_id: int = Field(alias='id')
    user_name: str = Field(validation_alias='name', serialization_alias='fullName')

# Validate with aliases
user = User(**{'id': 123, 'name': 'John Doe'})
print(user.user_id)
#> 123

# Serialize with aliases
print(user.model_dump(by_alias=True))
#> {'id': 123, 'fullName': 'John Doe'}

Field Metadata

title
str | None
Human-readable title for the field
description
str | None
Description of the field
examples
list[Any] | None
Example values for the field
deprecated
bool | str | None
Mark the field as deprecated
from pydantic import BaseModel, Field

class User(BaseModel):
    id: int = Field(
        title='User ID',
        description='Unique identifier for the user',
        examples=[1, 42, 123]
    )
    legacy_field: str = Field(
        deprecated='Use new_field instead',
        default=''
    )

# Access field info
print(User.model_fields['id'].description)
#> Unique identifier for the user

Serialization Control

exclude
bool | None
Whether to exclude the field from serialization
exclude_if
Callable[[Any], bool] | None
Function to determine if field should be excluded based on its value
from pydantic import BaseModel, Field

class User(BaseModel):
    id: int
    name: str
    password: str = Field(exclude=True)
    internal_id: int = Field(exclude_if=lambda v: v == 0)

user = User(id=1, name='John', password='secret123', internal_id=0)

print(user.model_dump())
#> {'id': 1, 'name': 'John'}
# password is excluded, internal_id is 0 so it's excluded

Validation Behavior

validate_default
bool | None
Whether to validate the default value
strict
bool | None
Whether to use strict validation for this field
frozen
bool | None
Whether the field is immutable after initialization
from pydantic import BaseModel, Field, ValidationError

class Config(BaseModel):
    port: int = Field(default=8080, validate_default=True, gt=0)
    strict_value: int = Field(strict=True)
    immutable_id: int = Field(frozen=True)

config = Config(strict_value=42, immutable_id=1)

try:
    Config(strict_value='42', immutable_id=1)  # strict mode rejects string
except ValidationError as e:
    print(e)
    '''
    1 validation error for Config
    strict_value
      Input should be a valid integer
    '''

# Frozen field cannot be modified
try:
    config.immutable_id = 2
except ValidationError as e:
    print(e)

Required vs Optional Fields

Required Fields

Fields without defaults are required:
from pydantic import BaseModel, Field

class User(BaseModel):
    id: int
    name: str = Field(...)  # Ellipsis also indicates required

# Missing required field raises error
try:
    User(id=1)
except ValidationError as e:
    print(e)

Optional Fields

Fields with defaults are optional:
from typing import Optional
from pydantic import BaseModel, Field

class User(BaseModel):
    id: int
    name: str = 'Anonymous'
    email: Optional[str] = None
    age: int = Field(default=0, ge=0)

user = User(id=1)
print(user.model_dump())
#> {'id': 1, 'name': 'Anonymous', 'email': None, 'age': 0}

Field Types

Standard Types

Pydantic supports all Python standard types:
from datetime import datetime, date
from decimal import Decimal
from typing import List, Dict, Set, Tuple
from pydantic import BaseModel

class Example(BaseModel):
    # Primitives
    integer: int
    floating: float
    text: str
    flag: bool
    
    # Collections
    items: List[int]
    mapping: Dict[str, str]
    unique: Set[str]
    pair: Tuple[int, str]
    
    # Date/Time
    timestamp: datetime
    birth_date: date
    
    # Decimal for precise numbers
    price: Decimal

example = Example(
    integer=42,
    floating=3.14,
    text='hello',
    flag=True,
    items=[1, 2, 3],
    mapping={'key': 'value'},
    unique={'a', 'b', 'c'},
    pair=(1, 'one'),
    timestamp=datetime.now(),
    birth_date=date(1990, 1, 1),
    price=Decimal('19.99')
)

Nested Models

Fields can be other Pydantic models:
from pydantic import BaseModel
from typing import List

class Address(BaseModel):
    street: str
    city: str
    zipcode: str

class User(BaseModel):
    id: int
    name: str
    address: Address
    previous_addresses: List[Address] = []

user = User(
    id=1,
    name='John',
    address={'street': '123 Main St', 'city': 'NYC', 'zipcode': '10001'},
    previous_addresses=[{'street': '456 Oak Ave', 'city': 'LA', 'zipcode': '90001'}]
)

print(user.address.city)
#> NYC

FieldInfo Attributes

The FieldInfo class contains comprehensive field metadata:
from pydantic import BaseModel, Field

class User(BaseModel):
    name: str = Field(description='User full name', min_length=1)

field_info = User.model_fields['name']
print(field_info.annotation)
#> <class 'str'>
print(field_info.description)
#> User full name
print(field_info.is_required())
#> True
print(field_info.metadata)
#> [MinLen(min_length=1)]

Best Practices

  • Use Field() to add validation constraints and metadata
  • Prefer default_factory over mutable defaults
  • Use aliases to map between different naming conventions
  • Add descriptions to improve API documentation
  • Use strict=True when you need exact type matching
  • Mark sensitive fields with exclude=True or use SecretStr
Never use mutable objects as default values:
# Bad
tags: List[str] = []

# Good
tags: List[str] = Field(default_factory=list)

Build docs developers (and LLMs) love