0
# Field Configuration
1
2
Fine-grained control over field-level serialization behavior. The configuration system allows customization of individual fields through encoders, decoders, naming conventions, exclusion rules, and marshmallow integration.
3
4
## Capabilities
5
6
### Field Configuration Function
7
8
The `config` function creates metadata dictionaries that control how individual dataclass fields are serialized and deserialized.
9
10
```python { .api }
11
def config(
12
metadata: Optional[dict] = None,
13
*,
14
encoder: Optional[Callable] = None,
15
decoder: Optional[Callable] = None,
16
mm_field: Optional[marshmallow.fields.Field] = None,
17
letter_case: Optional[Union[Callable[[str], str], LetterCase]] = None,
18
undefined: Optional[Union[str, Undefined]] = None,
19
field_name: Optional[str] = None,
20
exclude: Optional[Callable] = None
21
) -> Dict[str, dict]:
22
"""
23
Configure field-level serialization options.
24
25
Parameters:
26
- metadata: Existing metadata dict to extend
27
- encoder: Custom function to encode this field's value
28
- decoder: Custom function to decode this field's value
29
- mm_field: Marshmallow field instance for validation
30
- letter_case: Case conversion for this field's name
31
- undefined: Undefined parameter handling for this field
32
- field_name: Custom name for this field in JSON
33
- exclude: Function to determine if field should be excluded
34
35
Returns:
36
Metadata dictionary for use with dataclass field()
37
"""
38
```
39
40
Usage example:
41
42
```python
43
from dataclasses import dataclass, field
44
from dataclasses_json import dataclass_json, config
45
from datetime import datetime
46
47
@dataclass_json
48
@dataclass
49
class Event:
50
name: str
51
# Custom field name in JSON
52
event_date: datetime = field(metadata=config(field_name="date"))
53
# Custom encoder/decoder
54
priority: int = field(metadata=config(
55
encoder=lambda x: "high" if x > 5 else "low",
56
decoder=lambda x: 10 if x == "high" else 1
57
))
58
```
59
60
### Letter Case Conversion
61
62
The `LetterCase` enum provides standard case conversion strategies for field names.
63
64
```python { .api }
65
class LetterCase(Enum):
66
"""
67
Enumeration of supported letter case conversions for field names.
68
"""
69
CAMEL = camelcase # fieldName
70
KEBAB = spinalcase # field-name
71
SNAKE = snakecase # field_name
72
PASCAL = pascalcase # FieldName
73
```
74
75
Case conversion functions:
76
77
```python { .api }
78
def camelcase(string: str) -> str:
79
"""Convert string to camelCase format."""
80
81
def snakecase(string: str) -> str:
82
"""Convert string to snake_case format."""
83
84
def spinalcase(string: str) -> str:
85
"""Convert string to spinal-case (kebab-case) format."""
86
87
def pascalcase(string: str) -> str:
88
"""Convert string to PascalCase format."""
89
90
def capitalcase(string: str) -> str:
91
"""Convert string to capital case (first letter uppercase)."""
92
93
def uplowcase(string: str, case: str) -> str:
94
"""Convert string to upper or lower case.
95
96
Parameters:
97
- string: String to convert
98
- case: 'up' for uppercase, 'low' for lowercase
99
"""
100
```
101
102
Usage examples:
103
104
```python
105
from dataclasses import dataclass, field
106
from dataclasses_json import dataclass_json, config, LetterCase
107
108
# Global case conversion
109
@dataclass_json(letter_case=LetterCase.CAMEL)
110
@dataclass
111
class Product:
112
product_name: str # Becomes "productName" in JSON
113
unit_price: float # Becomes "unitPrice" in JSON
114
115
# Per-field case conversion
116
@dataclass_json
117
@dataclass
118
class Order:
119
order_id: str
120
# Override global case for this field
121
customer_name: str = field(metadata=config(letter_case=LetterCase.SNAKE))
122
```
123
124
### Field Exclusion
125
126
Control which fields are included in serialization based on dynamic conditions.
127
128
```python { .api }
129
class Exclude:
130
"""
131
Pre-defined exclusion predicates for field-level control.
132
"""
133
ALWAYS: Callable[[object], bool] = lambda _: True
134
NEVER: Callable[[object], bool] = lambda _: False
135
```
136
137
Usage example:
138
139
```python
140
from dataclasses import dataclass, field
141
from dataclasses_json import dataclass_json, config, Exclude
142
143
@dataclass_json
144
@dataclass
145
class User:
146
username: str
147
email: str
148
# Always exclude this field from serialization
149
password_hash: str = field(metadata=config(exclude=Exclude.ALWAYS))
150
# Conditionally exclude based on value
151
admin: bool = field(metadata=config(
152
exclude=lambda obj: not obj.admin # Only include if user is admin
153
))
154
```
155
156
### Custom Encoders and Decoders
157
158
Implement custom serialization logic for specific fields or types.
159
160
```python { .api }
161
# Encoder: Python value -> JSON-serializable value
162
EncoderFunc = Callable[[Any], Any]
163
164
# Decoder: JSON value -> Python value
165
DecoderFunc = Callable[[Any], Any]
166
```
167
168
Usage examples:
169
170
```python
171
from dataclasses import dataclass, field
172
from dataclasses_json import dataclass_json, config
173
from datetime import datetime, date
174
from decimal import Decimal
175
176
def date_encoder(dt: date) -> str:
177
"""Encode date as ISO string."""
178
return dt.isoformat()
179
180
def date_decoder(s: str) -> date:
181
"""Decode ISO string to date."""
182
return datetime.fromisoformat(s).date()
183
184
def decimal_encoder(d: Decimal) -> str:
185
"""Encode Decimal as string."""
186
return str(d)
187
188
def decimal_decoder(s: str) -> Decimal:
189
"""Decode string to Decimal."""
190
return Decimal(s)
191
192
@dataclass_json
193
@dataclass
194
class Invoice:
195
invoice_date: date = field(metadata=config(
196
encoder=date_encoder,
197
decoder=date_decoder
198
))
199
amount: Decimal = field(metadata=config(
200
encoder=decimal_encoder,
201
decoder=decimal_decoder
202
))
203
# Enum encoding
204
status: str = field(metadata=config(
205
encoder=lambda x: x.upper(),
206
decoder=lambda x: x.lower()
207
))
208
```
209
210
### Marshmallow Field Integration
211
212
Use marshmallow fields directly for advanced validation and transformation.
213
214
```python { .api }
215
# Marshmallow field types that can be used
216
from marshmallow import fields
217
218
# Common field types:
219
# fields.String, fields.Integer, fields.Float, fields.Boolean
220
# fields.DateTime, fields.Date, fields.Time
221
# fields.List, fields.Dict, fields.Nested
222
# fields.Email, fields.Url, fields.UUID
223
```
224
225
Usage example:
226
227
```python
228
from dataclasses import dataclass, field
229
from dataclasses_json import dataclass_json, config
230
from marshmallow import fields
231
from typing import List
232
233
@dataclass_json
234
@dataclass
235
class Contact:
236
# Email validation
237
email: str = field(metadata=config(mm_field=fields.Email()))
238
# URL validation
239
website: str = field(metadata=config(mm_field=fields.Url()))
240
# List with validation
241
tags: List[str] = field(metadata=config(
242
mm_field=fields.List(fields.String(validate=lambda x: len(x) > 0))
243
))
244
# Custom validation
245
age: int = field(metadata=config(
246
mm_field=fields.Integer(validate=lambda x: 0 <= x <= 150)
247
))
248
```
249
250
## Advanced Configuration Patterns
251
252
### Combining Configuration Options
253
254
```python
255
from dataclasses import dataclass, field
256
from dataclasses_json import dataclass_json, config, LetterCase
257
from marshmallow import fields
258
259
@dataclass_json
260
@dataclass
261
class AdvancedConfig:
262
# Multiple config options on one field
263
created_at: datetime = field(metadata=config(
264
field_name="timestamp",
265
encoder=lambda dt: int(dt.timestamp()),
266
decoder=lambda ts: datetime.fromtimestamp(ts),
267
mm_field=fields.Integer(validate=lambda x: x > 0)
268
))
269
```
270
271
### Configuration Inheritance
272
273
```python
274
# Base configuration can be extended
275
base_config = config(letter_case=LetterCase.CAMEL)
276
277
@dataclass_json
278
@dataclass
279
class BaseModel:
280
created_at: datetime = field(metadata=config(
281
base_config, # Extend base config
282
encoder=lambda dt: dt.isoformat()
283
))
284
```
285
286
### Conditional Configuration
287
288
```python
289
import os
290
291
# Environment-based configuration
292
DEBUG_MODE = os.getenv('DEBUG', 'false').lower() == 'true'
293
294
@dataclass_json
295
@dataclass
296
class ApiResponse:
297
data: dict
298
# Include debug info only in debug mode
299
debug_info: dict = field(metadata=config(
300
exclude=lambda obj: not DEBUG_MODE
301
))
302
```