forms.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import re
  2. from django import forms
  3. from django.utils.translation import gettext as _
  4. from .mixins import BootstrapMixin
  5. __all__ = (
  6. 'BulkEditForm',
  7. 'BulkRenameForm',
  8. 'ConfirmationForm',
  9. 'CSVModelForm',
  10. 'FilterForm',
  11. 'TableConfigForm',
  12. )
  13. class ConfirmationForm(BootstrapMixin, forms.Form):
  14. """
  15. A generic confirmation form. The form is not valid unless the `confirm` field is checked.
  16. """
  17. return_url = forms.CharField(
  18. required=False,
  19. widget=forms.HiddenInput()
  20. )
  21. confirm = forms.BooleanField(
  22. required=True,
  23. widget=forms.HiddenInput(),
  24. initial=True
  25. )
  26. class BulkEditForm(BootstrapMixin, forms.Form):
  27. """
  28. Provides bulk edit support for objects.
  29. """
  30. nullable_fields = ()
  31. class BulkRenameForm(BootstrapMixin, forms.Form):
  32. """
  33. An extendable form to be used for renaming objects in bulk.
  34. """
  35. find = forms.CharField()
  36. replace = forms.CharField(
  37. required=False
  38. )
  39. use_regex = forms.BooleanField(
  40. required=False,
  41. initial=True,
  42. label=_('Use regular expressions')
  43. )
  44. def clean(self):
  45. super().clean()
  46. # Validate regular expression in "find" field
  47. if self.cleaned_data['use_regex']:
  48. try:
  49. re.compile(self.cleaned_data['find'])
  50. except re.error:
  51. raise forms.ValidationError({
  52. 'find': "Invalid regular expression"
  53. })
  54. class CSVModelForm(forms.ModelForm):
  55. """
  56. ModelForm used for the import of objects in CSV format.
  57. """
  58. def __init__(self, *args, headers=None, fields=None, **kwargs):
  59. headers = headers or {}
  60. fields = fields or []
  61. super().__init__(*args, **kwargs)
  62. # Modify the model form to accommodate any customized to_field_name properties
  63. for field, to_field in headers.items():
  64. if to_field is not None:
  65. self.fields[field].to_field_name = to_field
  66. # Omit any fields not specified (e.g. because the form is being used to
  67. # updated rather than create objects)
  68. if fields:
  69. for field in list(self.fields.keys()):
  70. if field not in fields:
  71. del self.fields[field]
  72. class FilterForm(BootstrapMixin, forms.Form):
  73. """
  74. Base Form class for FilterSet forms.
  75. """
  76. q = forms.CharField(
  77. required=False,
  78. label=_('Search')
  79. )
  80. class TableConfigForm(BootstrapMixin, forms.Form):
  81. """
  82. Form for configuring user's table preferences.
  83. """
  84. available_columns = forms.MultipleChoiceField(
  85. choices=[],
  86. required=False,
  87. widget=forms.SelectMultiple(
  88. attrs={'size': 10, 'class': 'form-select'}
  89. ),
  90. label=_('Available Columns')
  91. )
  92. columns = forms.MultipleChoiceField(
  93. choices=[],
  94. required=False,
  95. widget=forms.SelectMultiple(
  96. attrs={'size': 10, 'class': 'form-select'}
  97. ),
  98. label=_('Selected Columns')
  99. )
  100. def __init__(self, table, *args, **kwargs):
  101. self.table = table
  102. super().__init__(*args, **kwargs)
  103. # Initialize columns field based on table attributes
  104. self.fields['available_columns'].choices = table.available_columns
  105. self.fields['columns'].choices = table.selected_columns
  106. @property
  107. def table_name(self):
  108. return self.table.__class__.__name__