Kim Stacks
Kim Stacks

Reputation: 10812

Django Rest Framework: how to make field required / read-only only for update actions such as PUT and PATCH?

I have a Django Serializer that has a field that should only be required for update actions such as PUT and PATCH. But not for create actions such as POST.

I found this similar SO question but there's no clue there regarding how to write a custom validation to detect whether an action is for create or update or patch.

Similarly, I want to turn on read_only (or make them not editable) for some other fields but only for update actions.

I have googled the django rest framework docs, but there's no explicit examples of such custom validators.

Right now, my workaround is to set required=false altogether which is not the best.

Please advise.

Upvotes: 13

Views: 8015

Answers (2)

aman kumar
aman kumar

Reputation: 3156

You can override the get_fields methods of serializer and then you can change the value of that fields

class SomeDataSerializer(serializers.ModelSerializer):
    some_field = serializers.CharField(max_length=100)

    def get_fields(self, *args, **kwargs):
        fields = super(SomeDataSerializer, self).get_fields(*args, **kwargs)
        request = self.context.get('request', None)
        if request and getattr(request, 'method', None) == "POST":
            fields['some_field'].required = False
        return fields

Upvotes: 21

Saad Aleem
Saad Aleem

Reputation: 1745

What I do in such situations is have a different serializer altogether that inherits from a base serializer and overrides the relevant fields. So in you case, an approach like this should work:

class CreateSerializer(serializers.Serializers):
    field = serializers.CharField(max_length=100)

class UpdateSerializer(CreateSerializer):
    field = serializers.CharField(max_length=100, required=False)

And in your view, return the relevant serializer:

def get_serializer_class(self):
    if self.request.action == "POST":
        return CreateSerializer
    elif self.request.action in ["PUT", "PATCH"]:
        return UpdateSerializer

I think this is a good approach to take because you might need to add additional logic in the future based on the request method. It's also more readable than monkey patching the field's required attribute.

Upvotes: 21

Related Questions