customfields.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. from django.contrib.contenttypes.models import ContentType
  2. from extras.models import *
  3. from extras.choices import CustomFieldVisibilityChoices
  4. __all__ = (
  5. 'CustomFieldsMixin',
  6. )
  7. class CustomFieldsMixin:
  8. """
  9. Extend a Form to include custom field support.
  10. Attributes:
  11. model: The model class
  12. """
  13. model = None
  14. def __init__(self, *args, **kwargs):
  15. self.custom_fields = {}
  16. super().__init__(*args, **kwargs)
  17. self._append_customfield_fields()
  18. def _get_content_type(self):
  19. """
  20. Return the ContentType of the form's model.
  21. """
  22. if not getattr(self, 'model', None):
  23. raise NotImplementedError(f"{self.__class__.__name__} must specify a model class.")
  24. return ContentType.objects.get_for_model(self.model)
  25. def _get_custom_fields(self, content_type):
  26. return CustomField.objects.filter(content_types=content_type)
  27. def _get_form_field(self, customfield):
  28. return customfield.to_form_field()
  29. def _append_customfield_fields(self):
  30. """
  31. Append form fields for all CustomFields assigned to this object type.
  32. """
  33. for customfield in self._get_custom_fields(self._get_content_type()):
  34. if customfield.ui_visibility == CustomFieldVisibilityChoices.VISIBILITY_HIDDEN:
  35. continue
  36. field_name = f'cf_{customfield.name}'
  37. self.fields[field_name] = self._get_form_field(customfield)
  38. if customfield.ui_visibility == CustomFieldVisibilityChoices.VISIBILITY_READ_ONLY:
  39. self.fields[field_name].disabled = True
  40. # Annotate the field in the list of CustomField form fields
  41. self.custom_fields[field_name] = customfield