Skip to content

Commit

Permalink
📝 Add documentation about AliasPath and AliasChoices (#6129)
Browse files Browse the repository at this point in the history
Co-authored-by: Terrence Dorsey <terrend@mishu.com>
  • Loading branch information
Kludex and tpdorsey committed Jun 14, 2023
1 parent 216f123 commit 0688792
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
70 changes: 70 additions & 0 deletions docs/usage/fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,74 @@ You can read more about [Alias Precedence](/usage/model_config/#alias-precedence
[`@typing.dataclass_transform`](https://docs.python.org/3/library/typing.html#typing.dataclass_transform)
decorator, such as Pyright.

### `AliasPath` and `AliasChoices`

Pydantic provides two special types for convenience when using `validation_alias`: `AliasPath` and `AliasChoices`.

The `AliasPath` is used to specify a path to a field using aliases. For example:

```py lint="skip"
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))

user = User.model_validate({'names': ['John', 'Doe']}) # (1)!
print(user)
#> first_name='John' last_name='Doe'
```

1. We are using `model_validate` to validate a dictionary using the field aliases.

You can see more details about [`model_validate`](/api/main/#pydantic.main.BaseModel.model_validate) in the API reference.

In the `'first_name'` field, we are using the alias `'names'` and the index `0` to specify the path to the first name.
In the `'last_name'` field, we are using the alias `'names'` and the index `1` to specify the path to the last name.

`AliasChoices` is used to specify a choice of aliases. For example:

```py lint="skip"
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'}) # (1)!
print(user)
#> first_name='John' last_name='Doe'
user = User.model_validate({'first_name': 'John', 'lname': 'Doe'}) # (2)!
print(user)
#> first_name='John' last_name='Doe'
```

1. We are using the second alias choice for both fields.
2. We are using the first alias choice for the field `'first_name'` and the second alias choice
for the field `'last_name'`.

You can also use `AliasChoices` with `AliasPath`:

```py lint="skip"
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'
```

TODO: Document usage of other `Field` keyword arguments
2 changes: 1 addition & 1 deletion docs/usage/model_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ print(voice.model_dump(by_alias=True))
```

The same precedence applies to `validation_alias` and `serialization_alias`.
See more about the different field aliases on [the dedicated section](/usage/fields.md#field-aliases).
See more about the different field aliases under [field aliases](fields.md#field-aliases).

## Extra Attributes

Expand Down

0 comments on commit 0688792

Please sign in to comment.