forms.py 3.5 KB

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