My Beta
model's stage field provides 5 choices. I want my serializer to not always accept all these choices but only some of them according to the serialized object's actual stage value. For example, if my_beta_object.stage == 1
, then the serializer should expect (and offer) only stages 2 and 3, if my_beta_object.stage == 2
, only stages 2 and 4, etc.
# models.py
class Beta(models.Model):
class BetaStage(models.IntegerChoices):
REQUESTED = (1, "has been requested")
ACCEPTED = (2, "has been accepted")
REFUSED = (3, "has been refused")
CORRECTED = (4, "has been corrected")
COMPLETED = (5, "has been completed")
stage = models.ChoiceField(choices=self.BetaStage.choices)
# serializers.py
class BetaActionSerializer(serializers.ModelSerializer):
stage = serializers.ChoiceField(
# choices=?
)
class Meta:
model = Beta
fields = ("stage",)
# views.py
class BetaViewSet(viewsets.ModelViewSet):
serializer_class = BetaSerializer
def get_serializer_class(self):
if self.action == "update":
return BetaActionSerializer
return self.serializer_class
How can I dynamically limit the choices of that field according to the serialized object's field value?
You could try to override the
__init__
method of your serializer and then dynamically generates the choices. However, it's not as simple aschoices=my_generated_choices
. It's a bit more complicated, and there's an in-depth solution on that topic over thereThe alternative and simpler method is to use the
validate()
method, which is triggered at the end of the validation process, after each field has been validated successfully. You could do the following:validate
method, ifupdating
, check if the new status is a valid choice based on your current status, using your static dictValidationError