helpers.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. from re import sub
  2. from jinja2 import contextfunction
  3. from flask import g, request, url_for, flash
  4. from wtforms.validators import DataRequired, InputRequired
  5. from flask_admin._compat import urljoin, urlparse, iteritems
  6. from ._compat import string_types
  7. def set_current_view(view):
  8. g._admin_view = view
  9. def get_current_view():
  10. """
  11. Get current administrative view.
  12. """
  13. return getattr(g, '_admin_view', None)
  14. def get_url(endpoint, **kwargs):
  15. """
  16. Alternative to Flask `url_for`.
  17. If there's current administrative view, will call its `get_url`. If there's none - will
  18. use generic `url_for`.
  19. :param endpoint:
  20. Endpoint name
  21. :param kwargs:
  22. View arguments
  23. """
  24. view = get_current_view()
  25. if not view:
  26. return url_for(endpoint, **kwargs)
  27. return view.get_url(endpoint, **kwargs)
  28. def is_required_form_field(field):
  29. """
  30. Check if form field has `DataRequired` or `InputRequired` validators.
  31. :param field:
  32. WTForms field to check
  33. """
  34. for validator in field.validators:
  35. if isinstance(validator, (DataRequired, InputRequired)):
  36. return True
  37. return False
  38. def is_form_submitted():
  39. """
  40. Check if current method is PUT or POST
  41. """
  42. return request and request.method in ('PUT', 'POST')
  43. def validate_form_on_submit(form):
  44. """
  45. If current method is PUT or POST, validate form and return validation status.
  46. """
  47. return is_form_submitted() and form.validate()
  48. def get_form_data():
  49. """
  50. If current method is PUT or POST, return concatenated `request.form` with
  51. `request.files` or `None` otherwise.
  52. """
  53. if is_form_submitted():
  54. formdata = request.form
  55. if request.files:
  56. formdata = formdata.copy()
  57. formdata.update(request.files)
  58. return formdata
  59. return None
  60. def is_field_error(errors):
  61. """
  62. Check if wtforms field has error without checking its children.
  63. :param errors:
  64. Errors list.
  65. """
  66. if isinstance(errors, (list, tuple)):
  67. for e in errors:
  68. if isinstance(e, string_types):
  69. return True
  70. return False
  71. def flash_errors(form, message):
  72. from flask_admin.babel import gettext
  73. for field_name, errors in iteritems(form.errors):
  74. errors = form[field_name].label.text + u": " + u", ".join(errors)
  75. flash(gettext(message, error=str(errors)), 'error')
  76. @contextfunction
  77. def resolve_ctx(context):
  78. """
  79. Resolve current Jinja2 context and store it for general consumption.
  80. """
  81. g._admin_render_ctx = context
  82. def get_render_ctx():
  83. """
  84. Get view template context.
  85. """
  86. return getattr(g, '_admin_render_ctx', None)
  87. def prettify_class_name(name):
  88. """
  89. Split words in PascalCase string into separate words.
  90. :param name:
  91. String to split
  92. """
  93. return sub(r'(?<=.)([A-Z])', r' \1', name)
  94. def is_safe_url(target):
  95. ref_url = urlparse(request.host_url)
  96. test_url = urlparse(urljoin(request.host_url, target))
  97. return (test_url.scheme in ('http', 'https') and
  98. ref_url.netloc == test_url.netloc)
  99. def get_redirect_target(param_name='url'):
  100. target = request.values.get(param_name)
  101. if target and is_safe_url(target):
  102. return target