Field alias types and specifications
An alias is an alternative name for a field, used when serializing and deserializing data. You can specify aliases in four ways: (1) `alias` on Field must be a str; (2) `validation_alias` on Field can be a str, AliasPath, or AliasChoices; (3) `serialization_alias` on Field must be a str; (4) `alias_generator` on Config can be a callable or an AliasGenerator instance.
AliasPath for nested field access
AliasPath is used with validation_alias to specify a path to a field using nested keys and indices. For example, AliasPath('names', 0) accesses index 0 of the 'names' key, and AliasPath('contact', 'address') accesses the 'address' key within the 'contact' dictionary.
AliasPath example with nested and indexed data
Example showing AliasPath usage: from pydantic import BaseModel, Field, AliasPath
class User(BaseModel):
first_name: str = Field(validation_alias=AliasPath('names', 0))
last_name: str = Field(validation_alias=AliasPath('names', 1))
address: str = Field(validation_alias=AliasPath('contact', 'address'))
user = User.model_validate({
'names': ['John', 'Doe'],
'contact': {'address': '221B Baker Street'}
})
print(user)
#> first_name='John' last_name='Doe' address='221B Baker Street'
AliasChoices for field alias alternatives
AliasChoices is used with validation_alias to specify multiple alias options for a field. Choices that appear first in the list have higher priority during validation. The first matching choice is used.
AliasChoices example with priority
Example showing AliasChoices usage: from pydantic import BaseModel, Field, AliasChoices
class User(BaseModel):
first_name: str = Field(validation_alias=AliasChoices('first_name', 'fname'))
last_name: str = Field(validation_alias=AliasChoices('last_name', 'lname'))
user = User.model_validate({'fname': 'John', 'lname': 'Doe'})
print(user)
#> first_name='John' last_name='Doe'
user = User.model_validate({'first_name': 'John', 'lname': 'Doe'})
print(user)
#> first_name='John' last_name='Doe'
user = User.model_validate({'first_name': 'John', 'fname': 'J', 'lname': 'Doe'})
print(user)
#> first_name='John' last_name='Doe'
AliasChoices combined with AliasPath
Example combining AliasChoices and AliasPath: from pydantic import BaseModel, Field, AliasPath, AliasChoices
class User(BaseModel):
first_name: str = Field(validation_alias=AliasChoices('first_name', AliasPath('names', 0)))
last_name: str = Field(validation_alias=AliasChoices('last_name', AliasPath('names', 1)))
user = User.model_validate({'first_name': 'John', 'last_name': 'Doe'})
print(user)
#> first_name='John' last_name='Doe'
user = User.model_validate({'names': ['John', 'Doe']})
print(user)
#> first_name='John' last_name='Doe'
user = User.model_validate({'names': ['John'], 'last_name': 'Doe'})
print(user)
#> first_name='John' last_name='Doe'
Built-in alias generators
Pydantic offers three built-in alias generators: to_pascal, to_camel, and to_snake. These can be used with the alias_generator parameter on Config to automatically generate aliases for all fields in a model.
alias_generator with callable example
Example using a callable as alias_generator: from pydantic import BaseModel, ConfigDict
class Tree(BaseModel):
model_config = ConfigDict(
alias_generator=lambda field_name: field_name.upper()
)
age: int
height: float
kind: str
t = Tree.model_validate({'AGE': 12, 'HEIGHT': 1.2, 'KIND': 'oak'})
print(t.model_dump(by_alias=True))
#> {'AGE': 12, 'HEIGHT': 1.2, 'KIND': 'oak'}
AliasGenerator class for different validation and serialization aliases
AliasGenerator is a class that allows you to specify multiple alias generators for a model. You can use it to specify different alias generators for validation and serialization, useful when you need different naming conventions for loading and saving data.
AliasGenerator example with separate validation and serialization
Example using AliasGenerator: from pydantic import AliasGenerator, BaseModel, ConfigDict
class Tree(BaseModel):
model_config = ConfigDict(
alias_generator=AliasGenerator(
validation_alias=lambda field_name: field_name.upper(),
serialization_alias=lambda field_name: field_name.title(),
)
)
age: int
height: float
kind: str
t = Tree.model_validate({'AGE': 12, 'HEIGHT': 1.2, 'KIND': 'oak'})
print(t.model_dump(by_alias=True))
#> {'Age': 12, 'Height': 1.2, 'Kind': 'oak'}
Explicit field alias takes precedence over alias_generator
If you specify an alias on a Field, it will take precedence over the generated alias by default. Example: a field with Field(alias='lang') will use 'lang' instead of any generated alias from alias_generator.
alias_priority field parameter behavior
The alias_priority parameter on a field controls whether an explicit alias is overridden by alias_generator. Possible values: (1) alias_priority=2 means the alias will NOT be overridden by alias_generator; (2) alias_priority=1 means the alias WILL be overridden by alias_generator; (3) not set: if alias is set, it will NOT be overridden; if alias is not set, it WILL be overridden. The same precedence applies to validation_alias and serialization_alias.
Alias precedence example
Example showing alias precedence: from pydantic import BaseModel, ConfigDict, Field
def to_camel(string: str) -> str:
return ''.join(word.capitalize() for word in string.split('_'))
class Voice(BaseModel):
model_config = ConfigDict(alias_generator=to_camel)
name: str
language_code: str = Field(alias='lang')
voice = Voice(Name='Filiz', lang='tr-TR')
print(voice.language_code)
#> tr-TR
print(voice.model_dump(by_alias=True))
#> {'Name': 'Filiz', 'lang': 'tr-TR'}
ConfigDict.validate_by_alias default behavior
ConfigDict.validate_by_alias is True by default. When True, aliases are used for validation. When False, aliases are not used for validation.
ConfigDict.validate_by_name default behavior
ConfigDict.validate_by_name is False by default. When True, field attribute names are used for validation. When False, field attribute names are not used for validation.
Cannot set both validate_by_alias and validate_by_name to False
You cannot set both ConfigDict.validate_by_alias and ConfigDict.validate_by_name to False. A user error is raised if both are set to False.
ConfigDict.serialize_by_alias default behavior
ConfigDict.serialize_by_alias is False by default. When True, aliases are used during serialization. When False, field names are used instead of aliases. This is inconsistent with validation defaults where aliases are used by default.
serialize_by_alias example
Example of configuring serialize_by_alias: from pydantic import BaseModel, ConfigDict, Field
class Model(BaseModel):
my_field: str = Field(serialization_alias='my_alias')
model_config = ConfigDict(serialize_by_alias=True)
m = Model(my_field='foo')
print(m.model_dump())
#> {'my_alias': 'foo'}
model_validate by_alias and by_name parameters
The model_validate() method accepts by_alias and by_name flags to control alias use for validation on a per-call basis. By default, by_alias is True and by_name is False. These flags are also available on model_validate_json(), model_validate_strings(), and TypeAdapter validation methods.
model_dump by_alias parameter
The model_dump() method accepts a by_alias flag to control whether aliases are used during serialization. By default, by_alias is False. This flag is also available on model_dump_json() and TypeAdapter methods.
validate_by_alias and validate_by_name both True example
Example with both validate_by_alias=True and validate_by_name=True: from pydantic import BaseModel, ConfigDict, Field
class Model(BaseModel):
my_field: str = Field(validation_alias='my_alias')
model_config = ConfigDict(validate_by_alias=True, validate_by_name=True)
print(repr(Model(my_alias='foo')))
#> Model(my_field='foo')
print(repr(Model(my_field='foo')))
#> Model(my_field='foo')
model_validate with both by_alias and by_name example
Example using model_validate with both by_alias=True and by_name=True: from pydantic import BaseModel, Field
class Model(BaseModel):
my_field: str = Field(validation_alias='my_alias')
m = Model.model_validate(
{'my_alias': 'foo'}, by_alias=True, by_name=True
)
print(repr(m))
#> Model(my_field='foo')
m = Model.model_validate(
{'my_field': 'foo'}, by_alias=True, by_name=True
)
print(repr(m))
#> Model(my_field='foo')
model_dump with by_alias example
Example using model_dump with by_alias=True: from pydantic import BaseModel, Field
class Model(BaseModel):
my_field: str = Field(serialization_alias='my_alias')
m = Model(my_field='foo')
print(m.model_dump(by_alias=True))
#> {'my_alias': 'foo'}
Cannot set both by_alias and by_name to False in model_validate
You cannot set both by_alias and by_name to False when calling model_validate(). A user error is raised if both are set to False.
Field and dataclasses.field can be used together in Pydantic dataclasses
Both pydantic.Field() and the stdlib dataclasses.field() functions can be used in Pydantic dataclasses. dataclasses.field() supports metadata for JSON Schema attributes, while Field() provides Pydantic validation constraints like ge and le.
Field usage example in dataclass with both stdlib and Pydantic field
import dataclasses
from pydantic import Field
from pydantic.dataclasses import dataclass
@dataclass
class User:
id: int
name: str = 'John Doe'
friends: list[int] = dataclasses.field(default_factory=lambda: [0])
age: int | None = dataclasses.field(
default=None,
metadata={'title': 'The age of the user', 'description': 'do not lie!'},
)
height: int | None = Field(
default=None, title='The height in cm', ge=50, le=300
)
user = User(id='42', height='250')
print(user) # User(id=42, name='John Doe', friends=[0], age=None, height=250)
This example shows using dataclasses.field() with metadata and Field() with validation constraints in the same dataclass.
Field() function usage and assignment
The Field() function is used to customize Pydantic model fields and behaves similarly to the standard library field() function for dataclasses. Fields are assigned using annotated attributes. Even though a field is assigned a value via Field(), it is still required and has no default value unless explicitly specified.
Annotated pattern for attaching field metadata
Pydantic supports the Annotated typing construct to attach metadata to field annotations. For example: Annotated[str, Field(strict=True), WithJsonSchema({'extra': 'data'})]. The advantage is that using this pattern does not confuse users into thinking f has a default value, allows arbitrary amounts of metadata elements, and enables reusable types. However, certain Field() arguments (default, default_factory, and alias) are understood by static type checkers for synthesizing __init__(), while the annotated pattern is not.
Type constraints in Annotated pattern
Validation constraints can be added to specific parts of a type using the Annotated pattern. For example: int_list: list[Annotated[int, Field(gt=0)]] will validate that each integer in the list is greater than 0. Be careful not to mix field and type metadata - apply Field() metadata to the top-level type for it to apply to the field.
model_fields attribute for field inspection
The fields of a model can be inspected using the model_fields class attribute (or __pydantic_fields__ for Pydantic dataclasses). It is a mapping of field names to their FieldInfo instances. The FieldInfo object contains properties like annotation, alias, and metadata. model_fields can only be accessed from the class object, not from instances (changed in v2.11).
Default values in fields
Default values can be provided using normal assignment syntax (name: str = 'John Doe') or using the default argument in Field(). In Pydantic V2, types annotated as Any or wrapped by Optional no longer receive an implicit default of None if no default is explicitly specified.
default_factory for field defaults
The default_factory argument accepts a callable that generates a default value. A default factory can take a single optional argument to receive already validated data as a dictionary (available since v2.10). The data argument will only contain already validated data based on field ordering, so fields used in default_factory must be defined before the field using the factory.
validate_default field parameter
By default, Pydantic does not validate default values. The validate_default field parameter (or the validate_default configuration value) can be used to enable validation of default values. For example: age: int = Field(default='twelve', validate_default=True) will raise a validation error.
Mutable default values behavior
If a mutable default value is not hashable, Pydantic will automatically create a deep copy of it when creating each model instance. This prevents the common Python bug where the same mutable object is reused across instances. No default factory is required.
Field alias types: alias, validation_alias, serialization_alias
Three ways to define aliases exist: Field(alias='foo') for both validation and serialization, Field(validation_alias='foo') for validation only, and Field(serialization_alias='foo') for serialization only. If validation_alias or serialization_alias are used together with alias, they take priority over alias for their respective operations.
Field alias example with alias parameter
Example using Field(alias='username'): User can be instantiated with User(username='johndoe'). During serialization with model_dump(by_alias=True), the output will be {'username': 'johndoe'}. The by_alias keyword argument defaults to False, or can be set via ConfigDict.serialize_by_alias.
serialization_alias example
Example using Field(serialization_alias='username'): User(name='johndoe') is used for validation with the field name. When serialized with model_dump(by_alias=True), it outputs {'username': 'johndoe'} using the serialization alias.
Alias priority and precedence
When validation_alias and alias are used together, validation_alias takes priority for validation. When serialization_alias and alias are used together, serialization_alias takes priority for serialization. The alias_priority field parameter controls the order of precedence when using alias_generator.
Static type checker behavior with aliases
Static type checkers will synthesize the __init__ method using the alias parameter instead of the field name. When using ConfigDict(validate_by_name=True), type checkers will error when the actual field name is used instead of the alias. Using the Annotated pattern with Field(alias=...) allows type checkers to use the field name while Pydantic uses both.
Field constraints
The Field() function can add constraints to specific types. Examples include: positive: int = Field(gt=0), short_str: str = Field(max_length=3), precise_decimal: Decimal = Field(max_digits=5, decimal_places=2). Available constraints depend on the type and are described in the standard library types documentation.
Constraints on union types
When adding constraints to a union type, if a member is None or the MISSING sentinel, constraints are automatically applied to the remaining type(s). For example: positive: int | None = Field(gt=0) or negative: Annotated[int | None, Field(lt=0)].
repr parameter for field representation
The repr parameter controls whether a field should be included in the string representation of the model. Example: name: str = Field(repr=True) includes it (default), age: int = Field(repr=False) excludes it.
discriminator parameter for unions
The discriminator parameter controls which field is used to discriminate between different models in a union. It can take either a field name string or a Discriminator instance. Example: pet: Cat | Dog = Field(discriminator='pet_type') uses the pet_type field to determine which model to use.
Discriminator with custom function
A Discriminator instance can wrap a custom function for complex discriminator logic. The function receives v (the input data) and should return the discriminator value. It must handle both dict and object cases. This is useful when different models have different discriminator field names.
frozen parameter for field immutability
The frozen parameter prevents a field from being assigned a new value after the model is created. Example: name: str = Field(frozen=True) will raise ValidationError with type=frozen_field if assignment is attempted.
exclude and exclude_if parameters
The exclude parameter controls whether a field should be excluded from model_dump() output. Example: age: int = Field(exclude=True) will not appear in the dumped output. The exclude_if parameter (added in v2.12) allows conditional exclusion.
deprecated parameter for fields
The deprecated parameter (added in v2.7.0) marks a field as deprecated. This emits a runtime deprecation warning when accessing the field and sets the deprecated keyword in the generated JSON schema. It accepts a string message, boolean True, or a @warnings.deprecated decorator instance.
deprecated field as string
Example: deprecated_field: Annotated[int, Field(deprecated='This is deprecated')]. The string value becomes the deprecation message and appears in the JSON schema with deprecated: True.
deprecated field as boolean
Example: deprecated_field: Annotated[int, Field(deprecated=True)]. Sets the deprecated keyword to True in the JSON schema without a custom message.
Accessing deprecated fields in validators
When accessing a deprecated field inside a validator, the deprecation warning will be emitted. Use warnings.catch_warnings() to explicitly ignore the deprecation warning within the validator.
JSON Schema customization field parameters
Field parameters used exclusively for JSON schema customization are: title, description, examples, and json_schema_extra. These parameters control how the field appears in the generated JSON schema.
computed_field decorator usage
The @computed_field decorator includes properties (or cached_property) when serializing a model or dataclass. The property is also included in the JSON schema in serialization mode. Example: @computed_field @property def volume(self) -> float: return self.width * self.height * self.depth.
computed_field decorator with exclude_if
The @computed_field decorator supports the exclude_if parameter (added in v2.13) to conditionally exclude computed fields from serialization output.
computed_field JSON schema behavior
Computed fields appear in the JSON schema with readOnly: True and are included in the required list. Pydantic does not perform additional logic on wrapped properties like validation or cache invalidation.
computed_field implicit property conversion
If not explicitly specified, @computed_field will implicitly convert the method to a @property. However, it is preferable to explicitly use @property for type checking purposes.
deprecated computed field
Computed fields can be marked as deprecated using the @deprecated decorator. Example: @computed_field @property @deprecated("'volume' is deprecated") def volume(self) -> float: ...
model_dump(by_alias=True) uses field serialization aliases
When calling model_dump(by_alias=True), fields are serialized using their serialization_alias if defined, instead of their field name. This allows customizing the output keys in the dumped dictionary.
Field-specific metadata in named type aliases limitation
Named type aliases do not support field-specific metadata like alias, default, and deprecated. Only metadata that can be applied to the annotated type itself is allowed, such as validation constraints (Field(gt=0)) and JSON metadata. This restriction exists to allow named aliases to be stored as JSON Schema definitions without eagerly inspecting the alias value.
Field function with validate_call decorator
The Field() function can be used with validate_call to provide extra information and validations for function parameters. When using Field without default or default_factory, the Annotated pattern is recommended so type checkers infer the parameter as required. Otherwise, Field can be used as a default value to trick type checkers.
validate_call with Field aliases
Aliases can be used with validate_call decorator as normal. A parameter can be defined with an alias using Field(alias='name'), allowing the function to be called with the alias name instead of the parameter name.