fields.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. from __future__ import unicode_literals
  2. from django.core.exceptions import ImproperlyConfigured
  3. from django import forms
  4. from django.forms.extras import SelectDateWidget
  5. from django.utils.translation import ugettext_lazy as _
  6. from mezzanine.conf import settings
  7. from mezzanine.core.forms import SplitSelectDateTimeWidget
  8. from mezzanine.utils.importing import import_dotted_path
  9. # Constants for all available field types.
  10. TEXT = 1
  11. TEXTAREA = 2
  12. EMAIL = 3
  13. CHECKBOX = 4
  14. CHECKBOX_MULTIPLE = 5
  15. SELECT = 6
  16. SELECT_MULTIPLE = 7
  17. RADIO_MULTIPLE = 8
  18. FILE = 9
  19. DATE = 10
  20. DATE_TIME = 11
  21. HIDDEN = 12
  22. NUMBER = 13
  23. URL = 14
  24. DOB = 15
  25. # Names for all available field types.
  26. NAMES = (
  27. (TEXT, _("Single line text")),
  28. (TEXTAREA, _("Multi line text")),
  29. (EMAIL, _("Email")),
  30. (NUMBER, _("Number")),
  31. (URL, _("URL")),
  32. (CHECKBOX, _("Check box")),
  33. (CHECKBOX_MULTIPLE, _("Check boxes")),
  34. (SELECT, _("Drop down")),
  35. (SELECT_MULTIPLE, _("Multi select")),
  36. (RADIO_MULTIPLE, _("Radio buttons")),
  37. (FILE, _("File upload")),
  38. (DATE, _("Date")),
  39. (DATE_TIME, _("Date/time")),
  40. (DOB, _("Date of birth")),
  41. (HIDDEN, _("Hidden")),
  42. )
  43. # Field classes for all available field types.
  44. CLASSES = {
  45. TEXT: forms.CharField,
  46. TEXTAREA: forms.CharField,
  47. EMAIL: forms.EmailField,
  48. CHECKBOX: forms.BooleanField,
  49. CHECKBOX_MULTIPLE: forms.MultipleChoiceField,
  50. SELECT: forms.ChoiceField,
  51. SELECT_MULTIPLE: forms.MultipleChoiceField,
  52. RADIO_MULTIPLE: forms.ChoiceField,
  53. FILE: forms.FileField,
  54. DATE: forms.DateField,
  55. DATE_TIME: forms.DateTimeField,
  56. DOB: forms.DateField,
  57. HIDDEN: forms.CharField,
  58. NUMBER: forms.FloatField,
  59. URL: forms.URLField,
  60. }
  61. # Widgets for field types where a specialised widget is required.
  62. WIDGETS = {
  63. TEXTAREA: forms.Textarea,
  64. CHECKBOX_MULTIPLE: forms.CheckboxSelectMultiple,
  65. RADIO_MULTIPLE: forms.RadioSelect,
  66. DATE: SelectDateWidget,
  67. DATE_TIME: SplitSelectDateTimeWidget,
  68. DOB: SelectDateWidget,
  69. HIDDEN: forms.HiddenInput,
  70. }
  71. # Some helper groupings of field types.
  72. CHOICES = (CHECKBOX, SELECT, RADIO_MULTIPLE)
  73. DATES = (DATE, DATE_TIME, DOB)
  74. MULTIPLE = (CHECKBOX_MULTIPLE, SELECT_MULTIPLE)
  75. # HTML5 Widgets
  76. html5_field = lambda name, base: type(str(""), (base,), {"input_type": name})
  77. if getattr(settings, "FORMS_USE_HTML5", False):
  78. WIDGETS.update({
  79. DATE: html5_field("date", forms.DateInput),
  80. DATE_TIME: html5_field("datetime", forms.DateTimeInput),
  81. DOB: html5_field("date", forms.DateInput),
  82. EMAIL: html5_field("email", forms.TextInput),
  83. NUMBER: html5_field("number", forms.TextInput),
  84. URL: html5_field("url", forms.TextInput),
  85. })
  86. # Allow extra fields types to be defined via the FORMS_EXTRA_FIELDS
  87. # setting, which should contain a sequence of three-item sequences,
  88. # each containing the ID, dotted import path for the field class,
  89. # and field name, for each custom field type.
  90. extra_fields = getattr(settings, "FORMS_EXTRA_FIELDS", [])
  91. for field_id, field_path, field_name in extra_fields:
  92. if field_id in CLASSES:
  93. err = "ID %s for field %s in FORMS_EXTRA_FIELDS already exists"
  94. raise ImproperlyConfigured(err % (field_id, field_name))
  95. CLASSES[field_id] = import_dotted_path(field_path)
  96. NAMES += ((field_id, _(field_name)),)
  97. # Similar to above but for widgets - expects a sequence of pairs,
  98. # each with a field ID as per above, and a dotted path to the custom
  99. # widget class to use for the corresponding form field.
  100. extra_widgets = getattr(settings, "FORMS_EXTRA_WIDGETS", [])
  101. for field_id, widget_path in extra_widgets:
  102. if field_id not in CLASSES:
  103. err = "ID %s in FORMS_EXTRA_WIDGETS does not match a field"
  104. raise ImproperlyConfigured(err % field_id)
  105. WIDGETS[field_id] = import_dotted_path(widget_path)