# Alias in V1 (`v0.35.0+`)

Tip

The following documentation introduces support for `Alias()` and `AliasPath()` added in `v0.35.0`. This feature is part of an experimental “V1 Opt-in” mode, detailed in the Field Guide to V1 Opt-in.

V1 features are available starting from `v0.33.0`. See Enabling V1 Experimental Features for more details.

`Alias()` and `AliasPath()` provide mechanisms to map JSON keys or nested paths to dataclass fields, enhancing serialization and deserialization in the `dataclass-wizard` library. These utilities build upon Python’s `dataclasses.field()`, enabling custom mappings for more flexible and powerful data handling.

An alias is an alternative name for a field, used when de/serializing data. This feature is introduced in v0.35.0.

You can specify an alias in the following ways:

- Using `Alias()` and passing alias(es) to `all`, `load`, or `dump`

- Using `Meta` setting `v1_field_to_alias`

For examples of how to use `all`, `load`, and `dump`, see Field Aliases.

## Field Aliases

Field aliases allow mapping one or more JSON key names to a dataclass field for de/serialization. This feature provides flexibility when working with JSON structures that may not directly match your Python dataclass definitions.

### Defining Aliases

There are three primary ways to define an alias:

- Single alias for all operations

    - `Alias('foo')`

- Separate aliases for de/serialization

    - `Alias(load='foo')` for de-serialization

    - `Alias(dump='foo')` for serialization

The `load` and `dump` parameters enable fine-grained control over how fields are handled during deserialization and serialization, respectively. If both are provided, the field can behave differently depending on the operation.

### Examples of Field Aliases

#### Using a Single Alias

You can use a single alias for both serialization and deserialization by passing the alias name directly to `Alias()`:

    from dataclasses import dataclass

    from dataclass_wizard import JSONPyWizard
    from dataclass_wizard.v1 import Alias

    @dataclass
    class User(JSONPyWizard):
        class _(JSONPyWizard.Meta):
            v1 = True

        name: str = Alias('username')

    user = User.from_dict({'username': 'johndoe'})
    print(user)
    # > User(name='johndoe')
    print(user.to_dict())
    # > {'username': 'johndoe'}

#### Using Separate Aliases for Serialization and Deserialization

To define distinct aliases for load and dump operations:

    from dataclasses import dataclass

    from dataclass_wizard import JSONPyWizard
    from dataclass_wizard.v1 import Alias

    @dataclass
    class User(JSONPyWizard):
        class _(JSONPyWizard.Meta):
            v1 = True

        name: str = Alias(load='username', dump='user_name')

    user = User.from_dict({'username': 'johndoe'})
    print(user)
    # > User(name='johndoe')
    print(user.to_dict())
    # > {'user_name': 'johndoe'}

#### Skipping Fields During Serialization

To exclude a field during serialization, use the `skip` parameter:

    from dataclasses import dataclass

    from dataclass_wizard import JSONPyWizard
    from dataclass_wizard.v1 import Alias

    @dataclass
    class User(JSONPyWizard):
        class _(JSONPyWizard.Meta):
            v1 = True

        name: str = Alias('username', skip=True)

    user = User.from_dict({'username': 'johndoe'})
    print(user.to_dict())  # > {}

#### Advanced Usage

Aliases can be combined with `typing.Annotated` to support complex scenarios. You can also use the `v1_field_to_alias` meta-setting for bulk aliasing:

    from dataclasses import dataclass
    from typing import Annotated
    from dataclass_wizard import JSONPyWizard
    from dataclass_wizard.v1 import Alias

    @dataclass
    class Test(JSONPyWizard):
        class _(JSONPyWizard.Meta):
            v1 = True
            v1_case = 'CAMEL'
            v1_field_to_alias = {
                'my_int': 'MyInt',
                '__load__': False,
            }

        my_str: str = Alias(load=('a_str', 'other_str'))
        my_bool_test: Annotated[bool, Alias(dump='myDumpedBool')]
        my_int: int
        other_int: int = Alias(dump='DumpedInt')

    t = Test.from_dict({'other_str': 'test', 'myBoolTest': 'T', 'myInt': '123', 'otherInt': 321.0})
    print(t.to_dict())
    # > {'my_str': 'test', 'myDumpedBool': True, 'MyInt': 123, 'DumpedInt': 321}

## Alias Paths

Maps one or more nested JSON paths to a dataclass field. See documentation on `AliasPath()` for more details.

Examples

Mapping multiple nested paths to a field:

    from dataclasses import dataclass
    from dataclass_wizard import fromdict, LoadMeta
    from dataclass_wizard.v1 import AliasPath

    @dataclass
    class Example:
        my_str: str = AliasPath('a.b.c.1', 'x.y["-1"].z', default="default_value")

    LoadMeta(v1=True).bind_to(Example)

    print(fromdict(Example, {'x': {'y': {'-1': {'z': 'some_value'}}}}))
    # > Example(my_str='some_value')

Using `typing.Annotated` with nested paths:

    from dataclasses import dataclass
    from typing import Annotated
    from dataclass_wizard import JSONPyWizard
    from dataclass_wizard.v1 import AliasPath

    @dataclass
    class Example(JSONPyWizard):
        class _(JSONPyWizard.Meta):
            v1 = True

        my_str: Annotated[str, AliasPath('my."7".nested.path.-321')]

    ex = Example.from_dict({'my': {'7': {'nested': {'path': {-321: 'Test'}}}}})
    print(ex)  # > Example(my_str='Test')