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

1from .. import widgets 

2from .core import Field 

3from wtforms.utils import unset_value 

4 

5__all__ = ("FormField",) 

6 

7 

8class FormField(Field): 

9 """ 

10 Encapsulate a form as a field in another form. 

11 

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

18 

19 widget = widgets.TableWidget() 

20 

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 ) 

38 

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 ) 

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