from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from rest_framework.exceptions import ValidationError from rest_polymorphic.serializers import ( PolymorphicSerializer as BasePolymorphicSerializer, ) class PolymorphicSerializer(BasePolymorphicSerializer): resource_type_field_name = "type" def to_resource_type(self, model_or_instance): return model_or_instance._meta.verbose_name class EnumCharField(serializers.ChoiceField): default_error_messages = {"invalid_choice": _('"{input}" is not a valid choice.')} def __init__(self, enum, **kwargs): self.enum = enum kwargs.setdefault("choices", [(item, item.value) for item in enum]) super().__init__(**kwargs) self.enum = enum def to_internal_value(self, value): value = super().to_representation(value) if not isinstance(value, self.enum): try: enum_name, enum_value = value.split(".", 1) if enum_name == self.enum.__name__: value = self.enum[enum_value] except ValueError: raise ValidationError(self.error_messages["invalid"], code="invalid") return value def to_representation(self, value): if isinstance(value, self.enum): return str(value) return value