Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/flask_wtf/form.py: 52%

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

65 statements  

1from flask import current_app 

2from flask import request 

3from flask import session 

4from markupsafe import Markup 

5from werkzeug.datastructures import CombinedMultiDict 

6from werkzeug.datastructures import ImmutableMultiDict 

7from werkzeug.utils import cached_property 

8from wtforms import Form 

9from wtforms.meta import DefaultMeta 

10from wtforms.widgets import HiddenInput 

11 

12from .csrf import _FlaskFormCSRF 

13 

14try: 

15 from .i18n import translations 

16except ImportError: 

17 translations = None # babel not installed 

18 

19 

20SUBMIT_METHODS = {"POST", "PUT", "PATCH", "DELETE"} 

21_Auto = object() 

22 

23 

24class FlaskForm(Form): 

25 """Flask-specific subclass of WTForms :class:`~wtforms.form.Form`. 

26 

27 If ``formdata`` is not specified, this will use :attr:`flask.request.form` 

28 and :attr:`flask.request.files`. Explicitly pass ``formdata=None`` to 

29 prevent this. 

30 """ 

31 

32 class Meta(DefaultMeta): 

33 csrf_class = _FlaskFormCSRF 

34 csrf_context = session # not used, provided for custom csrf_class 

35 

36 @cached_property 

37 def csrf(self): 

38 return current_app.config.get("WTF_CSRF_ENABLED", True) 

39 

40 @cached_property 

41 def csrf_secret(self): 

42 return current_app.config.get("WTF_CSRF_SECRET_KEY", current_app.secret_key) 

43 

44 @cached_property 

45 def csrf_field_name(self): 

46 return current_app.config.get("WTF_CSRF_FIELD_NAME", "csrf_token") 

47 

48 @cached_property 

49 def csrf_time_limit(self): 

50 return current_app.config.get("WTF_CSRF_TIME_LIMIT", 3600) 

51 

52 def wrap_formdata(self, form, formdata): 

53 if formdata is _Auto: 

54 if _is_submitted(): 

55 if request.files: 

56 return CombinedMultiDict((request.files, request.form)) 

57 elif request.form: 

58 return request.form 

59 elif request.is_json: 

60 return ImmutableMultiDict(request.get_json()) 

61 

62 return None 

63 

64 return formdata 

65 

66 def get_translations(self, form): 

67 if not current_app.config.get("WTF_I18N_ENABLED", True): 

68 return super().get_translations(form) 

69 

70 return translations 

71 

72 def __init__(self, formdata=_Auto, **kwargs): 

73 super().__init__(formdata=formdata, **kwargs) 

74 

75 def is_submitted(self): 

76 """Consider the form submitted if there is an active request and 

77 the method is ``POST``, ``PUT``, ``PATCH``, or ``DELETE``. 

78 """ 

79 

80 return _is_submitted() 

81 

82 def validate_on_submit(self, extra_validators=None): 

83 """Call :meth:`validate` only if the form is submitted. 

84 This is a shortcut for ``form.is_submitted() and form.validate()``. 

85 """ 

86 return self.is_submitted() and self.validate(extra_validators=extra_validators) 

87 

88 def hidden_tag(self, *fields): 

89 """Render the form's hidden fields in one call. 

90 

91 A field is considered hidden if it uses the 

92 :class:`~wtforms.widgets.HiddenInput` widget. 

93 

94 If ``fields`` are given, only render the given fields that 

95 are hidden. If a string is passed, render the field with that 

96 name if it exists. 

97 

98 .. versionchanged:: 0.13 

99 

100 No longer wraps inputs in hidden div. 

101 This is valid HTML 5. 

102 

103 .. versionchanged:: 0.13 

104 

105 Skip passed fields that aren't hidden. 

106 Skip passed names that don't exist. 

107 """ 

108 

109 def hidden_fields(fields): 

110 for f in fields: 

111 if isinstance(f, str): 

112 f = getattr(self, f, None) 

113 

114 if f is None or not isinstance(f.widget, HiddenInput): 

115 continue 

116 

117 yield f 

118 

119 return Markup("\n".join(str(f) for f in hidden_fields(fields or self))) 

120 

121 

122def _is_submitted(): 

123 """Consider the form submitted if there is an active request and 

124 the method is ``POST``, ``PUT``, ``PATCH``, or ``DELETE``. 

125 """ 

126 

127 return bool(request) and request.method in SUBMIT_METHODS