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

53 statements  

1from wtforms.utils import unset_value 

2 

3from .. import widgets 

4from .core import Field 

5 

6__all__ = ("FormField",) 

7 

8 

9class FormField(Field): 

10 """ 

11 Encapsulate a form as a field in another form. 

12 

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 """ 

19 

20 widget = widgets.TableWidget() 

21 

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 ) 

39 

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 ) 

46 

47 if data is unset_value: 

48 try: 

49 data = self.default() 

50 except TypeError: 

51 data = self.default 

52 self._obj = data 

53 

54 self.object_data = data 

55 

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) 

61 

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() 

69 

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 

79 

80 self.form.populate_obj(candidate) 

81 setattr(obj, name, candidate) 

82 

83 def __iter__(self): 

84 return iter(self.form) 

85 

86 def __getitem__(self, name): 

87 return self.form[name] 

88 

89 def __getattr__(self, name): 

90 return getattr(self.form, name) 

91 

92 @property 

93 def data(self): 

94 return self.form.data 

95 

96 @property 

97 def errors(self): 

98 return self.form.errors