Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

widgets.py 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import re
  2. from django.conf import settings
  3. from django import forms
  4. from django.template import Context
  5. from django.forms.widgets import FileInput
  6. from django.utils.encoding import force_unicode
  7. from django.template.loader import render_to_string
  8. from django.forms.util import flatatt
  9. class ImageInput(FileInput):
  10. """
  11. Widget prodiving a input element for file uploads based on the
  12. Django ``FileInput`` element. It hides the actual browser-specific
  13. input element and shows the available image for images that have
  14. been previously uploaded. Selecting the image will open the file
  15. dialog and allow for selecting a new or replacing image file.
  16. """
  17. template_name = 'partials/image_input_widget.html'
  18. attrs = {'accept': 'image/*'}
  19. def render(self, name, value, attrs=None):
  20. """
  21. Render the ``input`` field based on the defined ``template_name``. The
  22. image URL is take from *value* and is provided to the template as
  23. ``image_url`` context variable relative to ``MEDIA_URL``. Further
  24. attributes for the ``input`` element are provide in ``input_attrs`` and
  25. contain parameters specified in *attrs* and *name*.
  26. If *value* contains no valid image URL an empty string will be provided
  27. in the context.
  28. """
  29. if value is None:
  30. value = ''
  31. final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
  32. if value != '':
  33. # Only add the 'value' attribute if a value is non-empty.
  34. final_attrs['value'] = force_unicode(self._format_value(value))
  35. image_url = final_attrs.get('value', '')
  36. if image_url:
  37. image_url = "%s/%s" % (settings.MEDIA_URL, image_url)
  38. return render_to_string(self.template_name, Context({
  39. 'input_attrs': flatatt(final_attrs),
  40. 'image_url': image_url,
  41. 'image_id': "%s-image" % final_attrs['id'],
  42. }))
  43. class WYSIWYGTextArea(forms.Textarea):
  44. def __init__(self, *args, **kwargs):
  45. kwargs.setdefault('attrs', {})
  46. kwargs['attrs'].setdefault('class', '')
  47. kwargs['attrs']['class'] += ' wysiwyg'
  48. super(WYSIWYGTextArea, self).__init__(*args, **kwargs)
  49. def datetime_format_to_js_date_format(format):
  50. """
  51. Convert a Python datetime format to a date format suitable for use with JS
  52. date pickers
  53. """
  54. converted = format
  55. replacements = {
  56. '%Y': 'yy',
  57. '%m': 'mm',
  58. '%d': 'dd',
  59. '%H:%M': '',
  60. }
  61. for search, replace in replacements.iteritems():
  62. converted = converted.replace(search, replace)
  63. return converted.strip()
  64. def datetime_format_to_js_time_format(format):
  65. """
  66. Convert a Python datetime format to a time format suitable for use with JS
  67. date pickers
  68. """
  69. converted = format
  70. replacements = {
  71. '%Y': '',
  72. '%m': '',
  73. '%d': '',
  74. '%H': 'HH',
  75. '%M': 'mm',
  76. }
  77. for search, replace in replacements.iteritems():
  78. converted = converted.replace(search, replace)
  79. converted = re.sub('[-/][^%]', '', converted)
  80. return converted.strip()
  81. def add_js_formats(widget):
  82. """
  83. Set data attributes for date and time format on a widget
  84. """
  85. attrs = {
  86. 'data-dateFormat': datetime_format_to_js_date_format(
  87. widget.format),
  88. 'data-timeFormat': datetime_format_to_js_time_format(
  89. widget.format)
  90. }
  91. widget.attrs.update(attrs)
  92. class DatePickerInput(forms.DateInput):
  93. """
  94. DatePicker input that uses the jQuery UI datepicker. Data attributes are
  95. used to pass the date format to the JS
  96. """
  97. def __init__(self, *args, **kwargs):
  98. super(DatePickerInput, self).__init__(*args, **kwargs)
  99. add_js_formats(self)
  100. class DateTimePickerInput(forms.DateTimeInput):
  101. # Build a widget which uses the locale datetime format but without seconds.
  102. # We also use data attributes to pass these formats to the JS datepicker.
  103. def __init__(self, *args, **kwargs):
  104. include_seconds = kwargs.pop('include_seconds', False)
  105. super(DateTimePickerInput, self).__init__(*args, **kwargs)
  106. if not include_seconds:
  107. self.format = re.sub(':?%S', '', self.format)
  108. add_js_formats(self)