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.
From DRF v3 onwards, setting a field as read-only or write-only can use serializer field core arguments mentioned as follows. write_only. Set this to True to ensure that the field may be used when updating or creating an instance, but is not included when serializing the representation.
APIView allow us to define functions that match standard HTTP methods like GET, POST, PUT, PATCH, etc. Viewsets allow us to define functions that match to common API object actions like : LIST, CREATE, RETRIEVE, UPDATE, etc.
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.
Open auth/urls.py and add update profile endpoint. we should send a PUT request to API for checking update profile endpoint. We must add username, first_name, last_name and email. If fields passed validations, user profile will be changed.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With