Refactoring into the factory style

done while trying to fix an unrelated error; keeping this as a
stylistic change regardless
This commit is contained in:
Klaas van Schelven
2025-09-12 11:32:59 +02:00
parent a4e84fa0a3
commit 3156f05756
3 changed files with 30 additions and 19 deletions

View File

@@ -1,17 +1,22 @@
from rest_framework import serializers
class EnumLowercaseChoiceField(serializers.ChoiceField):
def make_enum_field(enum_cls, *, name=None):
def __init__(self, enum_cls, **kwargs):
self._to_value = {member.name.lower(): member.value for member in enum_cls}
super().__init__(choices=self._to_value, **kwargs)
self._to_name = {member.value: member.name.lower() for member in enum_cls}
class EnumChoiceField(serializers.ChoiceField):
_enum_cls = enum_cls
def to_representation(self, value):
# fails hard for invalid values (shouldn't happen, would imply data corruption)
return self._to_name[value]
def __init__(self, **kwargs):
self._to_value = {m.name.lower(): m.value for m in enum_cls}
self._to_name = {m.value: m.name.lower() for m in enum_cls}
super().__init__(choices=self._to_value, **kwargs)
def to_internal_value(self, data):
key = super().to_internal_value(data)
return self._to_value[key]
def to_representation(self, value):
return self._to_name[value]
def to_internal_value(self, data):
key = super().to_internal_value(data)
return self._to_value[key]
EnumChoiceField.__name__ = name or f"{enum_cls.__name__}Field"
return EnumChoiceField

View File

@@ -1,5 +1,5 @@
from rest_framework import serializers
from bugsink.api_fields import EnumLowercaseChoiceField
from bugsink.api_fields import make_enum_field
from teams.models import Team
from bugsink.api_mixins import ExpandableSerializerMixin
@@ -8,8 +8,11 @@ from teams.serializers import TeamDetailSerializer
from .models import Project, ProjectVisibility
ProjectVisibilityField = make_enum_field(ProjectVisibility)
class ProjectListSerializer(serializers.ModelSerializer):
visibility = EnumLowercaseChoiceField(ProjectVisibility)
visibility = ProjectVisibilityField()
dsn = serializers.CharField(read_only=True)
class Meta:
@@ -33,7 +36,7 @@ class ProjectListSerializer(serializers.ModelSerializer):
class ProjectDetailSerializer(ExpandableSerializerMixin, serializers.ModelSerializer):
expandable_fields = {"team": TeamDetailSerializer}
visibility = EnumLowercaseChoiceField(ProjectVisibility)
visibility = ProjectVisibilityField()
dsn = serializers.CharField(read_only=True)
class Meta:
@@ -58,7 +61,7 @@ class ProjectDetailSerializer(ExpandableSerializerMixin, serializers.ModelSerial
class ProjectCreateUpdateSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(read_only=True)
team = serializers.PrimaryKeyRelatedField(queryset=Team.objects.all())
visibility = EnumLowercaseChoiceField(ProjectVisibility, required=False)
visibility = ProjectVisibilityField(required=False)
class Meta:
model = Project

View File

@@ -1,10 +1,13 @@
from rest_framework import serializers
from bugsink.api_fields import EnumLowercaseChoiceField
from bugsink.api_fields import make_enum_field
from .models import Team, TeamVisibility
TeamVisibilityField = make_enum_field(TeamVisibility)
class TeamListSerializer(serializers.ModelSerializer):
visibility = EnumLowercaseChoiceField(TeamVisibility)
visibility = TeamVisibilityField()
class Meta:
model = Team
@@ -12,7 +15,7 @@ class TeamListSerializer(serializers.ModelSerializer):
class TeamDetailSerializer(serializers.ModelSerializer):
visibility = EnumLowercaseChoiceField(TeamVisibility)
visibility = TeamVisibilityField()
class Meta:
model = Team
@@ -21,7 +24,7 @@ class TeamDetailSerializer(serializers.ModelSerializer):
class TeamCreateUpdateSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(read_only=True)
visibility = EnumLowercaseChoiceField(TeamVisibility, required=False)
visibility = TeamVisibilityField(required=False)
class Meta:
model = Team