0
# Field Types
1
2
Comprehensive field type system for validation, marshalling, and documentation generation. Flask-RESTPlus provides a rich set of field types for handling different data formats including strings, numbers, dates, nested objects, and custom validators.
3
4
## Capabilities
5
6
### Base Field Classes
7
8
Foundation classes that provide common functionality for all field types.
9
10
```python { .api }
11
class Raw:
12
def __init__(self, default=None, attribute=None, title=None, description=None,
13
required=False, readonly=False, example=None, **kwargs):
14
"""
15
Base field class for all other fields.
16
17
Args:
18
default: Default value if field is missing
19
attribute (str, optional): Source attribute name if different from field name
20
title (str, optional): Field title for documentation
21
description (str, optional): Field description for documentation
22
required (bool): Whether field is required
23
readonly (bool): Whether field is read-only
24
example: Example value for documentation
25
**kwargs: Additional field options
26
"""
27
28
def format(self, value):
29
"""
30
Format the field value for output.
31
32
Args:
33
value: Raw field value
34
35
Returns:
36
Formatted value
37
"""
38
39
def output(self, key, obj, **kwargs):
40
"""
41
Extract and format field value from an object.
42
43
Args:
44
key (str): Field key
45
obj: Source object
46
**kwargs: Additional options
47
48
Returns:
49
Formatted field value
50
"""
51
52
class StringMixin:
53
def __init__(self, min_length=None, max_length=None, **kwargs):
54
"""
55
Mixin for string-based validation.
56
57
Args:
58
min_length (int, optional): Minimum string length
59
max_length (int, optional): Maximum string length
60
**kwargs: Additional field options
61
"""
62
63
class MinMaxMixin:
64
def __init__(self, min=None, max=None, **kwargs):
65
"""
66
Mixin for min/max constraints.
67
68
Args:
69
min: Minimum value
70
max: Maximum value
71
**kwargs: Additional field options
72
"""
73
74
class NumberMixin(MinMaxMixin):
75
def __init__(self, **kwargs):
76
"""
77
Mixin for numeric field validation.
78
79
Args:
80
**kwargs: Additional field options including min/max
81
"""
82
```
83
84
### String Fields
85
86
Field types for handling text data with various formatting and validation options.
87
88
```python { .api }
89
class String(StringMixin, Raw):
90
def __init__(self, enum=None, discriminator=None, **kwargs):
91
"""
92
String field with validation options.
93
94
Args:
95
enum (list, optional): List of allowed values
96
discriminator (str, optional): Discriminator property for polymorphism
97
**kwargs: Additional string field options (min_length, max_length, etc.)
98
"""
99
100
class FormattedString(StringMixin, Raw):
101
def __init__(self, src_str, **kwargs):
102
"""
103
String field with format string support.
104
105
Args:
106
src_str (str): Format string (e.g., "Hello {name}")
107
**kwargs: Additional string field options
108
"""
109
110
class ClassName(String):
111
def __init__(self, dash=False, **kwargs):
112
"""
113
String field that converts to class name format.
114
115
Args:
116
dash (bool): Use dash-case instead of camelCase
117
**kwargs: Additional string field options
118
"""
119
```
120
121
### Numeric Fields
122
123
Field types for handling numeric data with precision control and range validation.
124
125
```python { .api }
126
class Integer(NumberMixin, Raw):
127
def __init__(self, **kwargs):
128
"""
129
Integer field with range validation.
130
131
Args:
132
**kwargs: Additional numeric field options (min, max, etc.)
133
"""
134
135
class Float(NumberMixin, Raw):
136
def __init__(self, **kwargs):
137
"""
138
Float field with range validation.
139
140
Args:
141
**kwargs: Additional numeric field options (min, max, etc.)
142
"""
143
144
class Arbitrary(NumberMixin, Raw):
145
def __init__(self, **kwargs):
146
"""
147
Arbitrary precision decimal field.
148
149
Args:
150
**kwargs: Additional numeric field options (min, max, etc.)
151
"""
152
153
class Fixed(NumberMixin, Raw):
154
def __init__(self, decimals=5, **kwargs):
155
"""
156
Fixed precision decimal field.
157
158
Args:
159
decimals (int): Number of decimal places
160
**kwargs: Additional numeric field options (min, max, etc.)
161
"""
162
```
163
164
### Date and Time Fields
165
166
Field types for handling temporal data with various format support.
167
168
```python { .api }
169
class DateTime(MinMaxMixin, Raw):
170
def __init__(self, dt_format='iso8601', **kwargs):
171
"""
172
DateTime field with format support.
173
174
Args:
175
dt_format (str): Date format ('iso8601', 'rfc822', or custom format)
176
**kwargs: Additional datetime field options (min, max, etc.)
177
"""
178
179
class Date(DateTime):
180
def __init__(self, **kwargs):
181
"""
182
Date-only field (no time component).
183
184
Args:
185
**kwargs: Additional date field options
186
"""
187
```
188
189
### Boolean and URL Fields
190
191
Fields for handling boolean values and URL validation.
192
193
```python { .api }
194
class Boolean(Raw):
195
def __init__(self, **kwargs):
196
"""
197
Boolean field that accepts various true/false representations.
198
199
Args:
200
**kwargs: Additional field options
201
"""
202
203
class Url(StringMixin, Raw):
204
def __init__(self, endpoint=None, absolute=False, scheme=None, **kwargs):
205
"""
206
URL field with validation and URL generation support.
207
208
Args:
209
endpoint (str, optional): Flask endpoint for URL generation
210
absolute (bool): Generate absolute URLs
211
scheme (str, optional): URL scheme for absolute URLs
212
**kwargs: Additional URL field options
213
"""
214
```
215
216
### Complex Fields
217
218
Field types for handling nested data structures and collections.
219
220
```python { .api }
221
class Nested(Raw):
222
def __init__(self, model, allow_null=False, skip_none=False, **kwargs):
223
"""
224
Nested model field for embedding other models.
225
226
Args:
227
model (dict or Model): Nested model definition
228
allow_null (bool): Allow null values
229
skip_none (bool): Skip None values in nested object
230
**kwargs: Additional nested field options
231
"""
232
233
class List(Raw):
234
def __init__(self, cls_or_instance, **kwargs):
235
"""
236
List field for arrays of values.
237
238
Args:
239
cls_or_instance (Field): Field type for list items
240
**kwargs: Additional list field options
241
"""
242
243
class Polymorph(Nested):
244
def __init__(self, mapping, required=False, **kwargs):
245
"""
246
Polymorphic field that selects model based on discriminator.
247
248
Args:
249
mapping (dict): Mapping from discriminator values to models
250
required (bool): Whether field is required
251
**kwargs: Additional polymorphic field options
252
"""
253
254
class Wildcard(Raw):
255
def __init__(self, **kwargs):
256
"""
257
Field that accepts any additional properties not defined in model.
258
259
Args:
260
**kwargs: Additional wildcard field options
261
"""
262
```
263
264
### Field Validation Error
265
266
Exception class for field marshalling and validation errors.
267
268
```python { .api }
269
class MarshallingError(Exception):
270
def __init__(self, underlying_exception):
271
"""
272
Exception raised during field marshalling.
273
274
Args:
275
underlying_exception (Exception): The underlying exception that caused the error
276
"""
277
```
278
279
## Usage Examples
280
281
### Basic Field Usage
282
283
```python
284
from flask_restplus import Api, fields
285
286
api = Api()
287
288
# Simple fields
289
simple_model = api.model('Simple', {
290
'id': fields.Integer(required=True, description='Unique identifier'),
291
'name': fields.String(required=True, min_length=1, max_length=100),
292
'active': fields.Boolean(default=True),
293
'score': fields.Float(min=0.0, max=100.0),
294
'website': fields.Url(),
295
'created_at': fields.DateTime(dt_format='iso8601')
296
})
297
```
298
299
### String Field Variations
300
301
```python
302
from flask_restplus import Api, fields
303
304
api = Api()
305
306
string_examples = api.model('StringExamples', {
307
# Basic string
308
'name': fields.String(required=True),
309
310
# String with length constraints
311
'username': fields.String(min_length=3, max_length=20),
312
313
# String with allowed values (enum)
314
'status': fields.String(enum=['active', 'inactive', 'pending']),
315
316
# Formatted string
317
'greeting': fields.FormattedString('Hello {name}!'),
318
319
# Class name formatting
320
'css_class': fields.ClassName(dash=True), # converts to dash-case
321
322
# String with example and description
323
'description': fields.String(
324
description='Item description',
325
example='A high-quality product'
326
)
327
})
328
```
329
330
### Numeric Field Examples
331
332
```python
333
from flask_restplus import Api, fields
334
335
api = Api()
336
337
numeric_model = api.model('Numeric', {
338
# Integer with range
339
'age': fields.Integer(min=0, max=150),
340
341
# Float with precision
342
'price': fields.Float(min=0.0),
343
344
# Fixed decimal (for currency, etc.)
345
'amount': fields.Fixed(decimals=2),
346
347
# Arbitrary precision for very large numbers
348
'big_number': fields.Arbitrary(),
349
350
# Required numeric fields
351
'quantity': fields.Integer(required=True, min=1)
352
})
353
```
354
355
### Date and Time Fields
356
357
```python
358
from flask_restplus import Api, fields
359
360
api = Api()
361
362
datetime_model = api.model('DateTime', {
363
# ISO8601 datetime (default)
364
'created_at': fields.DateTime(),
365
366
# RFC822 datetime
367
'updated_at': fields.DateTime(dt_format='rfc822'),
368
369
# Custom datetime format
370
'custom_date': fields.DateTime(dt_format='%Y-%m-%d %H:%M:%S'),
371
372
# Date only (no time)
373
'birth_date': fields.Date(),
374
375
# DateTime with range constraints
376
'event_date': fields.DateTime(
377
min=datetime(2023, 1, 1),
378
max=datetime(2024, 12, 31)
379
)
380
})
381
```
382
383
### Nested and Complex Fields
384
385
```python
386
from flask_restplus import Api, fields
387
388
api = Api()
389
390
# Address model for nesting
391
address_model = api.model('Address', {
392
'street': fields.String(required=True),
393
'city': fields.String(required=True),
394
'country': fields.String(required=True),
395
'postal_code': fields.String()
396
})
397
398
# User model with nested address
399
user_model = api.model('User', {
400
'id': fields.Integer(required=True),
401
'name': fields.String(required=True),
402
403
# Nested model
404
'address': fields.Nested(address_model),
405
406
# Optional nested model
407
'billing_address': fields.Nested(address_model, allow_null=True),
408
409
# List of strings
410
'tags': fields.List(fields.String),
411
412
# List of nested models
413
'addresses': fields.List(fields.Nested(address_model)),
414
415
# List with validation
416
'scores': fields.List(fields.Float(min=0, max=100))
417
})
418
```
419
420
### Advanced Field Features
421
422
```python
423
from flask_restplus import Api, fields
424
425
api = Api()
426
427
# Custom attribute mapping
428
user_model = api.model('User', {
429
'id': fields.Integer(required=True),
430
'full_name': fields.String(attribute='name'), # Maps to 'name' in source data
431
'user_email': fields.String(attribute='email.primary'), # Nested attribute access
432
})
433
434
# Read-only fields
435
response_model = api.model('Response', {
436
'id': fields.Integer(readonly=True), # Won't be used for input validation
437
'created_at': fields.DateTime(readonly=True),
438
'name': fields.String(required=True)
439
})
440
441
# Fields with examples for documentation
442
documented_model = api.model('Documented', {
443
'name': fields.String(
444
required=True,
445
description='User full name',
446
example='John Doe'
447
),
448
'age': fields.Integer(
449
min=0,
450
max=150,
451
description='User age in years',
452
example=25
453
)
454
})
455
```
456
457
### Polymorphic Fields
458
459
```python
460
from flask_restplus import Api, fields
461
462
api = Api()
463
464
# Base animal model
465
animal_model = api.model('Animal', {
466
'name': fields.String(required=True),
467
'type': fields.String(required=True, discriminator=True)
468
})
469
470
# Dog specific model
471
dog_model = api.inherit('Dog', animal_model, {
472
'breed': fields.String(required=True),
473
'good_boy': fields.Boolean(default=True)
474
})
475
476
# Cat specific model
477
cat_model = api.inherit('Cat', animal_model, {
478
'lives_remaining': fields.Integer(min=0, max=9, default=9),
479
'attitude': fields.String(enum=['friendly', 'aloof', 'evil'])
480
})
481
482
# Model that can contain different animal types
483
zoo_model = api.model('Zoo', {
484
'name': fields.String(required=True),
485
'animals': fields.List(fields.Polymorph({
486
'dog': dog_model,
487
'cat': cat_model
488
}))
489
})
490
```
491
492
### Field Validation Handling
493
494
```python
495
from flask_restplus import Api, Resource, fields, marshal_with
496
497
api = Api()
498
499
user_model = api.model('User', {
500
'name': fields.String(required=True, min_length=2),
501
'age': fields.Integer(min=0, max=150),
502
'email': fields.String(required=True)
503
})
504
505
@api.route('/users')
506
class UserList(Resource):
507
@api.expect(user_model, validate=True) # Enable validation
508
@api.marshal_with(user_model)
509
def post(self):
510
# Validation errors will be automatically handled
511
# Invalid data will return 400 Bad Request with error details
512
data = api.payload
513
# Process validated data...
514
return data, 201
515
```
516
517
### Wildcard Fields
518
519
```python
520
from flask_restplus import Api, fields
521
522
api = Api()
523
524
# Model that accepts additional properties
525
flexible_model = api.model('Flexible', {
526
'id': fields.Integer(required=True),
527
'name': fields.String(required=True),
528
# Accept any additional properties
529
'*': fields.Wildcard()
530
})
531
532
# Usage: can include any additional fields beyond id and name
533
# {"id": 1, "name": "Test", "custom_field": "value", "another": 123}
534
```