meta.py 3.9 KB

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