or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

csrf.mdfields.mdforms.mdi18n.mdindex.mdvalidation.mdwidgets.md

fields.mddocs/

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

```