mixins.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. from django import forms
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.utils.translation import gettext as _
  4. from extras.choices import CustomFieldVisibilityChoices
  5. from extras.models import *
  6. from utilities.forms.fields import DynamicModelMultipleChoiceField
  7. __all__ = (
  8. 'CustomFieldsMixin',
  9. 'SavedFiltersMixin',
  10. )
  11. class CustomFieldsMixin:
  12. """
  13. Extend a Form to include custom field support.
  14. Attributes:
  15. model: The model class
  16. """
  17. model = None
  18. def __init__(self, *args, **kwargs):
  19. self.custom_fields = {}
  20. self.custom_field_groups = {}
  21. super().__init__(*args, **kwargs)
  22. self._append_customfield_fields()
  23. def _get_content_type(self):
  24. """
  25. Return the ContentType of the form's model.
  26. """
  27. if not getattr(self, 'model', None):
  28. raise NotImplementedError(f"{self.__class__.__name__} must specify a model class.")
  29. return ContentType.objects.get_for_model(self.model)
  30. def _get_custom_fields(self, content_type):
  31. return CustomField.objects.filter(content_types=content_type).exclude(
  32. ui_visibility=CustomFieldVisibilityChoices.VISIBILITY_HIDDEN
  33. )
  34. def _get_form_field(self, customfield):
  35. return customfield.to_form_field()
  36. def _append_customfield_fields(self):
  37. """
  38. Append form fields for all CustomFields assigned to this object type.
  39. """
  40. for customfield in self._get_custom_fields(self._get_content_type()):
  41. if customfield.ui_visibility == CustomFieldVisibilityChoices.VISIBILITY_HIDDEN:
  42. continue
  43. field_name = f'cf_{customfield.name}'
  44. self.fields[field_name] = self._get_form_field(customfield)
  45. # Annotate the field in the list of CustomField form fields
  46. self.custom_fields[field_name] = customfield
  47. if customfield.group_name not in self.custom_field_groups:
  48. self.custom_field_groups[customfield.group_name] = []
  49. self.custom_field_groups[customfield.group_name].append(field_name)
  50. class SavedFiltersMixin(forms.Form):
  51. filter_id = DynamicModelMultipleChoiceField(
  52. queryset=SavedFilter.objects.all(),
  53. required=False,
  54. label=_('Saved Filter'),
  55. query_params={
  56. 'usable': True,
  57. }
  58. )