meta.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from wtforms import i18n
  2. from wtforms.utils import WebobInputWrapper
  3. from wtforms.widgets.core import clean_key
  4. class DefaultMeta:
  5. """
  6. This is the default Meta class which defines all the default values and
  7. therefore also the 'API' of the class Meta interface.
  8. """
  9. # -- Basic form primitives
  10. def bind_field(self, form, unbound_field, options):
  11. """
  12. bind_field allows potential customization of how fields are bound.
  13. The default implementation simply passes the options to
  14. :meth:`UnboundField.bind`.
  15. :param form: The form.
  16. :param unbound_field: The unbound field.
  17. :param options:
  18. A dictionary of options which are typically passed to the field.
  19. :return: A bound field
  20. """
  21. return unbound_field.bind(form=form, **options)
  22. def wrap_formdata(self, form, formdata):
  23. """
  24. wrap_formdata allows doing custom wrappers of WTForms formdata.
  25. The default implementation detects webob-style multidicts and wraps
  26. them, otherwise passes formdata back un-changed.
  27. :param form: The form.
  28. :param formdata: Form data.
  29. :return: A form-input wrapper compatible with WTForms.
  30. """
  31. if formdata is not None and not hasattr(formdata, "getlist"):
  32. if hasattr(formdata, "getall"):
  33. return WebobInputWrapper(formdata)
  34. else:
  35. raise TypeError(
  36. "formdata should be a multidict-type wrapper that"
  37. " supports the 'getlist' method"
  38. )
  39. return formdata
  40. def render_field(self, field, render_kw):
  41. """
  42. render_field allows customization of how widget rendering is done.
  43. The default implementation calls ``field.widget(field, **render_kw)``
  44. """
  45. render_kw = {clean_key(k): v for k, v in render_kw.items()}
  46. other_kw = getattr(field, "render_kw", None)
  47. if other_kw is not None:
  48. other_kw = {clean_key(k): v for k, v in other_kw.items()}
  49. render_kw = dict(other_kw, **render_kw)
  50. return field.widget(field, **render_kw)
  51. # -- CSRF
  52. csrf = False
  53. csrf_field_name = "csrf_token"
  54. csrf_secret = None
  55. csrf_context = None
  56. csrf_class = None
  57. def build_csrf(self, form):
  58. """
  59. Build a CSRF implementation. This is called once per form instance.
  60. The default implementation builds the class referenced to by
  61. :attr:`csrf_class` with zero arguments. If `csrf_class` is ``None``,
  62. will instead use the default implementation
  63. :class:`wtforms.csrf.session.SessionCSRF`.
  64. :param form: The form.
  65. :return: A CSRF implementation.
  66. """
  67. if self.csrf_class is not None:
  68. return self.csrf_class()
  69. from wtforms.csrf.session import SessionCSRF
  70. return SessionCSRF()
  71. # -- i18n
  72. locales = False
  73. cache_translations = True
  74. translations_cache = {}
  75. def get_translations(self, form):
  76. """
  77. Override in subclasses to provide alternate translations factory.
  78. See the i18n documentation for more.
  79. :param form: The form.
  80. :return: An object that provides gettext() and ngettext() methods.
  81. """
  82. locales = self.locales
  83. if locales is False:
  84. return None
  85. if self.cache_translations:
  86. # Make locales be a hashable value
  87. locales = tuple(locales) if locales else None
  88. translations = self.translations_cache.get(locales)
  89. if translations is None:
  90. translations = self.translations_cache[locales] = i18n.get_translations(
  91. locales
  92. )
  93. return translations
  94. return i18n.get_translations(locales)
  95. # -- General
  96. def update_values(self, values):
  97. """
  98. Given a dictionary of values, update values on this `Meta` instance.
  99. """
  100. for key, value in values.items():
  101. setattr(self, key, value)