Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/wtforms/fields/form.py: 32%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from wtforms.utils import unset_value
3from .. import widgets
4from .core import Field
6__all__ = ("FormField",)
9class FormField(Field):
10 """
11 Encapsulate a form as a field in another form.
13 :param form_class:
14 A subclass of Form that will be encapsulated.
15 :param separator:
16 A string which will be suffixed to this field's name to create the
17 prefix to enclosed fields. The default is fine for most uses.
18 """
20 widget = widgets.TableWidget()
22 def __init__(
23 self, form_class, label=None, validators=None, separator="-", **kwargs
24 ):
25 super().__init__(label, validators, **kwargs)
26 self.form_class = form_class
27 self.separator = separator
28 self._obj = None
29 if self.filters:
30 raise TypeError(
31 "FormField cannot take filters, as the encapsulated"
32 " data is not mutable."
33 )
34 if validators:
35 raise TypeError(
36 "FormField does not accept any validators. Instead,"
37 " define them on the enclosed form."
38 )
40 def process(self, formdata, data=unset_value, extra_filters=None):
41 if extra_filters:
42 raise TypeError(
43 "FormField cannot take filters, as the encapsulateddata is not mutable."
44 )
46 if data is unset_value:
47 try:
48 data = self.default()
49 except TypeError:
50 data = self.default
51 self._obj = data
53 self.object_data = data
55 prefix = self.name + self.separator
56 if isinstance(data, dict):
57 self.form = self.form_class(formdata=formdata, prefix=prefix, **data)
58 else:
59 self.form = self.form_class(formdata=formdata, obj=data, prefix=prefix)
61 def validate(self, form, extra_validators=()):
62 if extra_validators:
63 raise TypeError(
64 "FormField does not accept in-line validators, as it"
65 " gets errors from the enclosed form."
66 )
67 return self.form.validate()
69 def populate_obj(self, obj, name):
70 candidate = getattr(obj, name, None)
71 if candidate is None:
72 if self._obj is None:
73 raise TypeError(
74 "populate_obj: cannot find a value to populate from"
75 " the provided obj or input data/defaults"
76 )
77 candidate = self._obj
79 self.form.populate_obj(candidate)
80 setattr(obj, name, candidate)
82 def __iter__(self):
83 return iter(self.form)
85 def __getitem__(self, name):
86 return self.form[name]
88 def __getattr__(self, name):
89 return getattr(self.form, name)
91 @property
92 def data(self):
93 return self.form.data
95 @property
96 def errors(self):
97 return self.form.errors