Serialization Options¶
Note
Future Behavior Change: Starting in v1.0.0
, keys will no longer be automatically converted to camelCase.
Instead, the default behavior will match the field names defined in the dataclass.
To preserve the current camelCase conversion, you can explicitly enable it using JSONPyWizard
.
For a deeper dive into upcoming changes and new features introduced in V1 Opt-in, refer to the Field Guide to V1 Opt‐in.
The following parameters can be used to fine-tune and control how the serialization of a
dataclass instance to a Python dict
object or JSON string is handled.
Skip Defaults¶
A common use case is skipping fields with default values - based on the default
or default_factory
argument to dataclasses.field()
- in the serialization
process.
The attribute skip_defaults
in the inner Meta
class can be enabled, to exclude
such field values from serialization.The to_dict()
method (or the asdict()
helper
function) can also be passed an exclude
argument, containing a list of one or more
dataclass field names to exclude from the serialization process. An example of both these
approaches is shown below.
from collections import defaultdict
from dataclasses import field, dataclass
from dataclass_wizard import JSONWizard
@dataclass
class MyClass(JSONWizard):
class _(JSONWizard.Meta):
skip_defaults = True
my_str: str
other_str: str = 'any value'
optional_str: str = None
my_list: list[str] = field(default_factory=list)
my_dict: defaultdict[str, list[float]] = field(
default_factory=lambda: defaultdict(list))
print('-- Load (Deserialize)')
c = MyClass('abc')
print(f'Instance: {c!r}')
print('-- Dump (Serialize)')
string = c.to_json()
print(string)
assert string == '{"myStr": "abc"}'
print('-- Dump (with `skip_defaults=False`)')
print(c.to_dict(skip_defaults=False))
Exclude Fields¶
You can also exclude specific dataclass fields (and their values) from the serialization process. There are two approaches that can be used for this purpose:
The argument
dump=False
can be passed in to thejson_key()
andjson_field()
helper functions. Note that this is a more permanent option, as opposed to the one below.The
to_dict()
method (or theasdict()
helper function ) can be passed anexclude
argument, containing a list of one or more dataclass field names to exclude from the serialization process.
Additionally, here is an example to demonstrate usage of both these approaches:
from dataclasses import dataclass
from typing import Annotated
from dataclass_wizard import JSONWizard, json_key, json_field
@dataclass
class MyClass(JSONWizard):
my_str: str
my_int: int
other_str: Annotated[str, json_key('AnotherStr', dump=False)]
my_bool: bool = json_field('TestBool', dump=False)
data = {'MyStr': 'my string',
'myInt': 1,
'AnotherStr': 'testing 123',
'TestBool': True}
print('-- From Dict')
c = MyClass.from_dict(data)
print(f'Instance: {c!r}')
# dynamically exclude the `my_int` field from serialization
additional_exclude = ('my_int',)
print('-- To Dict')
out_dict = c.to_dict(exclude=additional_exclude)
print(out_dict)
assert out_dict == {'myStr': 'my string'}
“Skip If” Functionality¶
The Dataclass Wizard offers powerful, configurable options to skip serializing fields under specific conditions. This functionality is available both globally (via the Meta class) and per-field (using type annotations or dataclasses.Field wrappers).
Overview¶
You can:
- Globally skip fields that match a condition using Meta.skip_if
or Meta.skip_defaults_if
.
- Conditionally skip fields individually using type annotations with SkipIf
, or the skip_if_field
wrapper for dataclasses.Field
.
Built-in Helpers: For added flexibility, use helpers like IS_TRUTHY
, IS_FALSY
, and others for common conditions.
Note: SkipIfNone
is an alias for SkipIf(IS(None))
.
1. Global Field Skipping¶
1.1 Skip Any Field Matching a Condition¶
Use the skip_if
option in your dataclass’s Meta
configuration to skip fields that meet a specific condition during serialization.
from dataclasses import dataclass
from dataclass_wizard import JSONWizard, IS_NOT
@dataclass
class Example(JSONWizard):
class _(JSONWizard.Meta):
skip_if = IS_NOT(True) # Skip if the field is not `True`.
my_str: 'str | None'
my_bool: bool
other_bool: bool = False
ex = Example(my_str=None, my_bool=True)
assert ex.to_dict() == {'my_bool': True} # Only `my_bool` is serialized.
1.2 Skip Fields with Default Values Matching a Condition¶
Use the skip_defaults_if
option to skip serializing fields with default values that match a condition.
from dataclasses import dataclass
from dataclass_wizard import JSONWizard, IS
@dataclass
class Example(JSONWizard):
class _(JSONWizard.Meta):
skip_defaults_if = IS(None) # Skip fields with default value `None`.
my_str: str | None
my_bool: bool = False
ex = Example(my_str=None)
assert ex.to_dict() == {'my_str': None} # Explicitly set `None` values are not skipped.
1.3 Skip Fields Based on Truthy/Falsy Values¶
Use the IS_TRUTHY
and IS_FALSY
helpers for conditions based on truthiness or falsiness.
from dataclasses import dataclass
from dataclass_wizard import JSONWizard, IS_TRUTHY
@dataclass
class Example(JSONWizard):
class _(JSONWizard.Meta):
skip_if = IS_TRUTHY() # Skip fields that evaluate to True.
my_bool: bool
my_none: None = None
ex = Example(my_bool=True, my_none=None)
assert ex.to_dict() == {'my_none': None} # Only `my_none` is serialized.
2. Per-Field Skipping¶
For finer control, fields can be skipped individually using type annotations with SkipIf
or by wrapping dataclasses.Field
with skip_if_field
.
2.1 Using Type Annotations¶
You can use SkipIf
in conjunction with Annotated
to conditionally skip individual fields during serialization.
from dataclasses import dataclass
from typing import Annotated
from dataclass_wizard import JSONWizard, SkipIf, IS
@dataclass
class Example(JSONWizard):
my_str: Annotated['str | None', SkipIf(IS(None))] # Skip if `my_str is None`.
2.2 Using skip_if_field
Wrapper¶
Use skip_if_field
to add conditions directly to dataclasses.Field
:
from dataclasses import dataclass
from dataclass_wizard import JSONWizard, skip_if_field, EQ
@dataclass
class Example(JSONWizard):
third_str: 'str | None' = skip_if_field(EQ(''), default=None) # Skip if empty string.
2.3 Combined Example¶
Both approaches can be used together to achieve granular control:
from dataclasses import dataclass
from typing import Annotated
from dataclass_wizard import JSONWizard, SkipIf, skip_if_field, IS, EQ
@dataclass
class Example(JSONWizard):
my_str: Annotated['str | None', SkipIf(IS(None))] # Skip if `my_str is None`.
third_str: 'str | None' = skip_if_field(EQ(''), default=None) # Skip if `third_str` is ''.
ex = Example(my_str='test', third_str='')
assert ex.to_dict() == {'my_str': 'test'}
Key Classes and Utilities¶
SkipIf
: Adds skipping logic to a field via type annotations.skip_if_field
: Wrapsdataclasses.Field
for inline skipping logic.Condition Helpers:
IS
,IS_NOT
: Skip based on identity.EQ
,NE
,LT
,LE
,GT
,GE
: Skip based on comparison.IS_TRUTHY
,IS_FALSY
: Skip fields based on truthiness or falsiness.Alias:
SkipIfNone
is equivalent toSkipIf(IS(None))
.
Performance and Clarity¶
This design ensures both performance and self-documenting code, while enabling complex serialization rules effortlessly.