Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/wtforms/fields/form.py: 32%
53 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:32 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:32 +0000
1from .. import widgets
2from .core import Field
3from wtforms.utils import unset_value
5__all__ = ("FormField",)
8class FormField(Field):
9 """
10 Encapsulate a form as a field in another form.
12 :param form_class:
13 A subclass of Form that will be encapsulated.
14 :param separator:
15 A string which will be suffixed to this field's name to create the
16 prefix to enclosed fields. The default is fine for most uses.
17 """
19 widget = widgets.TableWidget()
21 def __init__(
22 self, form_class, label=None, validators=None, separator="-", **kwargs
23 ):
24 super().__init__(label, validators, **kwargs)
25 self.form_class = form_class
26 self.separator = separator
27 self._obj = None
28 if self.filters:
29 raise TypeError(
30 "FormField cannot take filters, as the encapsulated"
31 " data is not mutable."
32 )
33 if validators:
34 raise TypeError(
35 "FormField does not accept any validators. Instead,"
36 " define them on the enclosed form."
37 )
39 def process(self, formdata, data=unset_value, extra_filters=None):
40 if extra_filters:
41 raise TypeError(
42 "FormField cannot take filters, as the encapsulated"
43 "data 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