customfields.py 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. from django.utils.translation import gettext as _
  2. from drf_spectacular.types import OpenApiTypes
  3. from drf_spectacular.utils import extend_schema_field
  4. from rest_framework import serializers
  5. from core.models import ObjectType
  6. from extras.choices import *
  7. from extras.models import CustomField, CustomFieldChoiceSet
  8. from netbox.api.fields import ChoiceField, ContentTypeField
  9. from netbox.api.serializers import ChangeLogMessageSerializer, ValidatedModelSerializer
  10. from users.api.serializers_.mixins import OwnerMixin
  11. __all__ = (
  12. 'CustomFieldChoiceSetSerializer',
  13. 'CustomFieldSerializer',
  14. )
  15. class CustomFieldChoiceSetSerializer(OwnerMixin, ChangeLogMessageSerializer, ValidatedModelSerializer):
  16. base_choices = ChoiceField(
  17. choices=CustomFieldChoiceSetBaseChoices,
  18. required=False,
  19. allow_null=True,
  20. )
  21. extra_choices = serializers.ListField(
  22. child=serializers.ListField(
  23. min_length=2,
  24. max_length=2
  25. )
  26. )
  27. choice_colors = serializers.DictField(
  28. child=serializers.ChoiceField(choices=CustomFieldChoiceColorChoices),
  29. required=False,
  30. )
  31. choices_count = serializers.IntegerField(read_only=True)
  32. class Meta:
  33. model = CustomFieldChoiceSet
  34. fields = [
  35. 'id', 'url', 'display_url', 'display', 'name', 'description', 'base_choices', 'extra_choices',
  36. 'choice_colors', 'order_alphabetically', 'choices_count', 'owner', 'created', 'last_updated',
  37. ]
  38. brief_fields = ('id', 'url', 'display', 'name', 'description', 'choices_count')
  39. class CustomFieldSerializer(OwnerMixin, ChangeLogMessageSerializer, ValidatedModelSerializer):
  40. object_types = ContentTypeField(
  41. queryset=ObjectType.objects.with_feature('custom_fields'),
  42. many=True
  43. )
  44. type = ChoiceField(choices=CustomFieldTypeChoices)
  45. related_object_type = ContentTypeField(
  46. queryset=ObjectType.objects.all(),
  47. required=False,
  48. allow_null=True
  49. )
  50. filter_logic = ChoiceField(choices=CustomFieldFilterLogicChoices, required=False)
  51. data_type = serializers.SerializerMethodField()
  52. choice_set = CustomFieldChoiceSetSerializer(
  53. nested=True,
  54. required=False,
  55. allow_null=True
  56. )
  57. ui_visible = ChoiceField(choices=CustomFieldUIVisibleChoices, required=False)
  58. ui_editable = ChoiceField(choices=CustomFieldUIEditableChoices, required=False)
  59. class Meta:
  60. model = CustomField
  61. fields = [
  62. 'id', 'url', 'display_url', 'display', 'object_types', 'type', 'related_object_type', 'data_type',
  63. 'name', 'label', 'group_name', 'description', 'required', 'unique', 'search_weight', 'filter_logic',
  64. 'ui_visible', 'ui_editable', 'is_cloneable', 'nulls_first', 'default', 'related_object_filter', 'weight',
  65. 'validation_minimum', 'validation_maximum', 'validation_regex', 'validation_schema', 'choice_set',
  66. 'owner', 'comments', 'created', 'last_updated',
  67. ]
  68. brief_fields = ('id', 'url', 'display', 'name', 'description')
  69. def validate_type(self, value):
  70. if self.instance and self.instance.type != value:
  71. raise serializers.ValidationError(_('Changing the type of custom fields is not supported.'))
  72. return value
  73. @extend_schema_field(OpenApiTypes.STR)
  74. def get_data_type(self, obj):
  75. types = CustomFieldTypeChoices
  76. if obj.type == types.TYPE_INTEGER:
  77. return 'integer'
  78. if obj.type == types.TYPE_DECIMAL:
  79. return 'decimal'
  80. if obj.type == types.TYPE_BOOLEAN:
  81. return 'boolean'
  82. if obj.type in (types.TYPE_JSON, types.TYPE_OBJECT):
  83. return 'object'
  84. if obj.type in (types.TYPE_MULTISELECT, types.TYPE_MULTIOBJECT):
  85. return 'array'
  86. return 'string'