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 encapsulated"
44 "data is not mutable."
45 )
47 if data is unset_value:
48 try:
49 data = self.default()
50 except TypeError:
51 data = self.default
52 self._obj = data
54 self.object_data = data
56 prefix = self.name + self.separator
57 if isinstance(data, dict):
58 self.form = self.form_class(formdata=formdata, prefix=prefix, **data)
59 else:
60 self.form = self.form_class(formdata=formdata, obj=data, prefix=prefix)
62 def validate(self, form, extra_validators=()):
63 if extra_validators:
64 raise TypeError(
65 "FormField does not accept in-line validators, as it"
66 " gets errors from the enclosed form."
67 )
68 return self.form.validate()
70 def populate_obj(self, obj, name):
71 candidate = getattr(obj, name, None)
72 if candidate is None:
73 if self._obj is None:
74 raise TypeError(
75 "populate_obj: cannot find a value to populate from"
76 " the provided obj or input data/defaults"
77 )
78 candidate = self._obj
80 self.form.populate_obj(candidate)
81 setattr(obj, name, candidate)
83 def __iter__(self):
84 return iter(self.form)
86 def __getitem__(self, name):
87 return self.form[name]
89 def __getattr__(self, name):
90 return getattr(self.form, name)
92 @property
93 def data(self):
94 return self.form.data
96 @property
97 def errors(self):
98 return self.form.errors