0
# Field Types
1
2
Comprehensive collection of form field types for handling different data types including text, numbers, dates, choices, files, and complex nested structures. All fields inherit from the base Field class and provide data processing, validation, and HTML rendering.
3
4
## Capabilities
5
6
### Core Field Infrastructure
7
8
Base classes and infrastructure that all fields inherit from.
9
10
```python { .api }
11
class Field:
12
"""
13
Base class for all form fields.
14
15
Parameters:
16
- label: Field label text or Label object
17
- validators: List/tuple of validator instances
18
- filters: List/tuple of data filters (functions that transform data)
19
- description: Help text for the field
20
- id: HTML id attribute (auto-generated if not provided)
21
- default: Default value for the field
22
- widget: Widget instance for HTML rendering
23
- render_kw: Dict of extra attributes for widget rendering
24
- name: Field name (usually set automatically)
25
"""
26
def __init__(self, label=None, validators=None, filters=(),
27
description="", id=None, default=None, widget=None,
28
render_kw=None, name=None, _form=None, _prefix="",
29
_translations=None, _meta=None): ...
30
31
def validate(self, form, extra_validators=()) -> bool:
32
"""Run validation chain, returns True if valid."""
33
34
def process(self, formdata, data=None, extra_filters=None):
35
"""Process raw form data into field data."""
36
37
def populate_obj(self, obj, name):
38
"""Set attribute on object with field data."""
39
40
def __call__(self, **kwargs) -> str:
41
"""Render field as HTML string."""
42
43
def gettext(self, string) -> str:
44
"""Get translated string."""
45
46
def ngettext(self, singular, plural, n) -> str:
47
"""Get translated string with pluralization."""
48
49
# Properties
50
data: any # Processed field value
51
raw_data: list # Raw input data from form
52
errors: tuple # Validation error messages
53
process_errors: tuple # Processing error messages
54
label: Label # Label object
55
flags: Flags # Widget flags for HTML attributes
56
validators: tuple # Validator instances
57
widget: Widget # Widget for rendering
58
59
class UnboundField:
60
"""
61
Unbound field for class-level field definitions.
62
63
Parameters:
64
- field_class: Field class to instantiate
65
- *args, **kwargs: Arguments for field constructor
66
"""
67
def __init__(self, field_class, *args, **kwargs): ...
68
def bind(self, name, form, **kwargs) -> Field: ...
69
70
class Label:
71
"""HTML form label wrapper."""
72
def __init__(self, field_id, text): ...
73
def __call__(self, text=None, **kwargs) -> str: ... # Render label HTML
74
75
class Flags:
76
"""Container for field flags/attributes used by widgets."""
77
def __getattr__(self, name): ...
78
def __setattr__(self, name, value): ...
79
```
80
81
### Text and String Fields
82
83
Basic text input fields for string data with various input types and constraints.
84
85
```python { .api }
86
class StringField(Field):
87
"""
88
Basic text input field.
89
Widget: TextInput()
90
"""
91
def __init__(self, label=None, validators=None, **kwargs): ...
92
93
class TextAreaField(Field):
94
"""
95
Multi-line text input field.
96
Widget: TextArea()
97
"""
98
def __init__(self, label=None, validators=None, **kwargs): ...
99
100
class PasswordField(Field):
101
"""
102
Password input field (doesn't render current value for security).
103
Widget: PasswordInput()
104
"""
105
def __init__(self, label=None, validators=None, **kwargs): ...
106
107
class HiddenField(Field):
108
"""
109
Hidden form field.
110
Widget: HiddenInput()
111
"""
112
def __init__(self, label=None, validators=None, **kwargs): ...
113
114
class SearchField(Field):
115
"""
116
HTML5 search input field.
117
Widget: SearchInput()
118
"""
119
def __init__(self, label=None, validators=None, **kwargs): ...
120
121
class TelField(Field):
122
"""
123
HTML5 telephone input field.
124
Widget: TelInput()
125
"""
126
def __init__(self, label=None, validators=None, **kwargs): ...
127
128
class URLField(Field):
129
"""
130
HTML5 URL input field.
131
Widget: URLInput()
132
"""
133
def __init__(self, label=None, validators=None, **kwargs): ...
134
135
class EmailField(Field):
136
"""
137
HTML5 email input field.
138
Widget: EmailInput()
139
"""
140
def __init__(self, label=None, validators=None, **kwargs): ...
141
142
class ColorField(Field):
143
"""
144
HTML5 color input field.
145
Widget: ColorInput()
146
"""
147
def __init__(self, label=None, validators=None, **kwargs): ...
148
```
149
150
### Numeric Fields
151
152
Fields for handling numeric data with appropriate validation and widgets.
153
154
```python { .api }
155
class IntegerField(Field):
156
"""
157
Integer input field with numeric validation.
158
Widget: NumberInput()
159
"""
160
def __init__(self, label=None, validators=None, **kwargs): ...
161
162
class FloatField(Field):
163
"""
164
Float input field with numeric validation.
165
Widget: NumberInput(step="any")
166
"""
167
def __init__(self, label=None, validators=None, **kwargs): ...
168
169
class DecimalField(Field):
170
"""
171
Decimal input field with precision control.
172
Widget: NumberInput(step="any")
173
174
Parameters:
175
- places: Number of decimal places (None for no rounding)
176
- rounding: Decimal rounding mode
177
- use_locale: Use locale-specific number formatting
178
- number_format: Custom number format string
179
"""
180
def __init__(self, label=None, validators=None, places=None,
181
rounding=None, use_locale=False, number_format=None, **kwargs): ...
182
183
class IntegerRangeField(Field):
184
"""
185
HTML5 range input for integers.
186
Widget: RangeInput()
187
"""
188
def __init__(self, label=None, validators=None, **kwargs): ...
189
190
class DecimalRangeField(Field):
191
"""
192
HTML5 range input for decimal values.
193
Widget: RangeInput()
194
"""
195
def __init__(self, label=None, validators=None, **kwargs): ...
196
```
197
198
### Boolean and Submit Fields
199
200
Fields for boolean values and form submission.
201
202
```python { .api }
203
class BooleanField(Field):
204
"""
205
Boolean checkbox field.
206
Widget: CheckboxInput()
207
208
Parameters:
209
- false_values: Iterable of values considered False (default: (False, "false", ""))
210
"""
211
def __init__(self, label=None, validators=None, false_values=None, **kwargs): ...
212
213
class SubmitField(Field):
214
"""
215
Submit button field.
216
Widget: SubmitInput()
217
"""
218
def __init__(self, label=None, validators=None, **kwargs): ...
219
```
220
221
### Date and Time Fields
222
223
Fields for handling date and time data with format parsing.
224
225
```python { .api }
226
class DateTimeField(Field):
227
"""
228
DateTime input field with format parsing.
229
Widget: DateTimeInput()
230
231
Parameters:
232
- format: strptime format string for parsing (default: "%Y-%m-%d %H:%M:%S")
233
"""
234
def __init__(self, label=None, validators=None, format="%Y-%m-%d %H:%M:%S", **kwargs): ...
235
236
class DateField(Field):
237
"""
238
Date input field with format parsing.
239
Widget: DateInput()
240
241
Parameters:
242
- format: strptime format string for parsing (default: "%Y-%m-%d")
243
"""
244
def __init__(self, label=None, validators=None, format="%Y-%m-%d", **kwargs): ...
245
246
class TimeField(Field):
247
"""
248
Time input field with format parsing.
249
Widget: TimeInput()
250
251
Parameters:
252
- format: strptime format string for parsing (default: "%H:%M")
253
"""
254
def __init__(self, label=None, validators=None, format="%H:%M", **kwargs): ...
255
256
class MonthField(Field):
257
"""
258
HTML5 month input field.
259
Widget: MonthInput()
260
"""
261
def __init__(self, label=None, validators=None, **kwargs): ...
262
263
class WeekField(Field):
264
"""
265
HTML5 week input field.
266
Widget: WeekInput()
267
"""
268
def __init__(self, label=None, validators=None, **kwargs): ...
269
270
class DateTimeLocalField(Field):
271
"""
272
HTML5 datetime-local input field.
273
Widget: DateTimeLocalInput()
274
"""
275
def __init__(self, label=None, validators=None, **kwargs): ...
276
```
277
278
### Choice Fields
279
280
Fields for selecting from predefined options.
281
282
```python { .api }
283
class SelectFieldBase(Field):
284
"""
285
Abstract base class for choice fields.
286
"""
287
def iter_choices(self):
288
"""Iterator yielding (value, label, selected, render_kw) tuples."""
289
290
def has_groups(self) -> bool:
291
"""Returns True if choices have optgroups."""
292
293
def iter_groups(self):
294
"""Iterator yielding (group_label, choices) tuples."""
295
296
class SelectField(SelectFieldBase):
297
"""
298
Select dropdown field.
299
Widget: Select()
300
301
Parameters:
302
- choices: List of (value, label) tuples or dict
303
- coerce: Function to coerce form data (default: str)
304
- validate_choice: Whether to validate selection is in choices (default: True)
305
"""
306
def __init__(self, label=None, validators=None, coerce=str, choices=None,
307
validate_choice=True, **kwargs): ...
308
309
class SelectMultipleField(SelectField):
310
"""
311
Multiple selection field.
312
Widget: Select(multiple=True)
313
"""
314
def __init__(self, label=None, validators=None, **kwargs): ...
315
316
class RadioField(SelectField):
317
"""
318
Radio button list field.
319
Widget: ListWidget(prefix_label=False)
320
Option Widget: RadioInput()
321
"""
322
def __init__(self, label=None, validators=None, **kwargs): ...
323
```
324
325
### File Fields
326
327
Fields for file uploads.
328
329
```python { .api }
330
class FileField(Field):
331
"""
332
File upload field.
333
Widget: FileInput()
334
"""
335
def __init__(self, label=None, validators=None, **kwargs): ...
336
337
class MultipleFileField(FileField):
338
"""
339
Multiple file upload field.
340
Widget: FileInput(multiple=True)
341
"""
342
def __init__(self, label=None, validators=None, **kwargs): ...
343
```
344
345
### Complex Fields
346
347
Fields for handling nested forms and dynamic lists.
348
349
```python { .api }
350
class FormField(Field):
351
"""
352
Embed another form as a field.
353
Widget: TableWidget()
354
355
Parameters:
356
- form_class: Form class to embed
357
- separator: Separator for nested field names (default: "-")
358
"""
359
def __init__(self, form_class, label=None, validators=None, separator="-", **kwargs): ...
360
361
class FieldList(Field):
362
"""
363
Dynamic list of repeated fields.
364
Widget: ListWidget()
365
366
Parameters:
367
- unbound_field: UnboundField instance for list entries
368
- min_entries: Minimum number of entries (default: 0)
369
- max_entries: Maximum number of entries (default: None)
370
- separator: Separator for indexed field names (default: "-")
371
- default: Default value factory (default: ())
372
"""
373
def __init__(self, unbound_field, label=None, validators=None,
374
min_entries=0, max_entries=None, separator="-", default=(), **kwargs): ...
375
376
def append_entry(self, data=None) -> Field:
377
"""Add new entry to the list, returns the new field."""
378
379
def pop_entry(self) -> Field:
380
"""Remove and return the last entry."""
381
```
382
383
## Field Usage Examples
384
385
### Basic Field Usage
386
387
```python
388
from wtforms import Form, StringField, IntegerField, validators
389
390
class ProductForm(Form):
391
name = StringField('Product Name', [
392
validators.DataRequired(),
393
validators.Length(max=100)
394
])
395
price = DecimalField('Price', [
396
validators.NumberRange(min=0),
397
validators.DataRequired()
398
], places=2)
399
description = TextAreaField('Description')
400
401
# Access field data
402
form = ProductForm(formdata=request.form)
403
if form.validate():
404
product_name = form.name.data
405
product_price = form.price.data
406
```
407
408
### Choice Field Usage
409
410
```python
411
class UserForm(Form):
412
country = SelectField('Country', choices=[
413
('us', 'United States'),
414
('ca', 'Canada'),
415
('mx', 'Mexico')
416
])
417
418
languages = SelectMultipleField('Languages', choices=[
419
('en', 'English'),
420
('es', 'Spanish'),
421
('fr', 'French')
422
])
423
424
notification_method = RadioField('Notifications', choices=[
425
('email', 'Email'),
426
('sms', 'SMS'),
427
('none', 'None')
428
])
429
430
# Dynamic choices
431
def get_categories():
432
return [(c.id, c.name) for c in Category.query.all()]
433
434
class ArticleForm(Form):
435
title = StringField('Title')
436
category = SelectField('Category', coerce=int)
437
438
def __init__(self, *args, **kwargs):
439
super().__init__(*args, **kwargs)
440
self.category.choices = get_categories()
441
```
442
443
### Date and Time Field Usage
444
445
```python
446
class EventForm(Form):
447
name = StringField('Event Name')
448
start_date = DateField('Start Date')
449
start_time = TimeField('Start Time')
450
end_datetime = DateTimeField('End Date & Time')
451
452
# Custom date format
453
custom_date = DateField('Custom Date', format='%d/%m/%Y')
454
455
# Access datetime data
456
form = EventForm(formdata=request.form)
457
if form.validate():
458
event_start = datetime.combine(
459
form.start_date.data,
460
form.start_time.data
461
)
462
```
463
464
### Complex Field Usage
465
466
```python
467
class AddressForm(Form):
468
street = StringField('Street')
469
city = StringField('City')
470
zipcode = StringField('Zip Code')
471
472
class ContactForm(Form):
473
name = StringField('Name')
474
475
# Embedded form
476
address = FormField(AddressForm)
477
478
# Dynamic list of phone numbers
479
phone_numbers = FieldList(StringField('Phone'), min_entries=1)
480
481
# Process nested data
482
form = ContactForm(formdata=request.form)
483
if form.validate():
484
contact_name = form.name.data
485
street_address = form.address.street.data
486
all_phones = [phone.data for phone in form.phone_numbers]
487
```
488
489
### Custom Field Validation
490
491
```python
492
class EmailListField(Field):
493
"""Custom field that accepts comma-separated email addresses."""
494
495
def process_formdata(self, valuelist):
496
if valuelist:
497
self.data = [email.strip() for email in valuelist[0].split(',')]
498
else:
499
self.data = []
500
501
def validate(self, form, extra_validators=()):
502
super().validate(form, extra_validators)
503
504
for email in self.data:
505
if not re.match(r'^[^@]+@[^@]+\.[^@]+$', email):
506
raise ValidationError(f'Invalid email: {email}')
507
508
class NewsletterForm(Form):
509
subject = StringField('Subject')
510
recipients = EmailListField('Recipients')
511
```
512
513
### File Upload Usage
514
515
```python
516
class DocumentForm(Form):
517
title = StringField('Document Title')
518
file = FileField('Upload File', [validators.DataRequired()])
519
attachments = MultipleFileField('Additional Files')
520
521
# Process file uploads
522
form = DocumentForm(formdata=request.form, files=request.files)
523
if form.validate():
524
uploaded_file = form.file.data # FileStorage object
525
filename = uploaded_file.filename
526
uploaded_file.save(f'/uploads/{filename}')
527
528
# Handle multiple files
529
for attachment in form.attachments.data:
530
if attachment.filename:
531
attachment.save(f'/uploads/{attachment.filename}')
532
```