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 encapsulateddata is not mutable." 

44 ) 

45 

46 if data is unset_value: 

47 try: 

48 data = self.default() 

49 except TypeError: 

50 data = self.default 

51 self._obj = data 

52 

53 self.object_data = data 

54 

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) 

60 

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

68 

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 

78 

79 self.form.populate_obj(candidate) 

80 setattr(obj, name, candidate) 

81 

82 def __iter__(self): 

83 return iter(self.form) 

84 

85 def __getitem__(self, name): 

86 return self.form[name] 

87 

88 def __getattr__(self, name): 

89 return getattr(self.form, name) 

90 

91 @property 

92 def data(self): 

93 return self.form.data 

94 

95 @property 

96 def errors(self): 

97 return self.form.errors