Reputation: 356
I am building a rest API and am wondering both about HTTP best practices I guess, and how that would apply to the DRF. When sending a PUT request, in the body, do requests have all of the parameters for objects that they would be manipulating? Even if not all of them are changing? Or do they only send the fields that are being updated? So for example if we had a House
object with No. of rooms
and floors
, and I was changing No. of rooms
should I only send that parameter, or both of them?
If requests should only contain the fields that are being updating, then how would that translate to the DjangoRestFramework? Any help would be greatly appreciated!
My Views are:
class HouseDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = House.objects.all()
serializer_class = HouseSerializer
and serializer is:
class HouseSerializer(serializers.ModelSerializer):
quotes = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = House
fields = (
'pk',
'address',
'quotes',
)
Upvotes: 1
Views: 352
Reputation:
PUT
is for full resource updates, PATCH
is for partial resource updates because Fielding says so.
Therefore, in your example, if you wanted to only update a No. of rooms
for your HouseDetail
model, you would send the following payload in a PATCH
request:
{ "no. of rooms": "42" }
It is still possible to partially update things with a PUT
request in DRF
(explained below) but you should simply use PATCH
for that because it was created for this. You get PUT
and PATCH
functionality for your model because you have subclassed the generics.RetrieveUpdateDestroyAPIView
class and have defined a serializer.
If a required field is omitted in your PUT
request (see documentation for required
), then you will receive a 400
status code with a response like {"detail": "x field is required"}
. However, when you request via PATCH
, there is a partial=True
argument passed to the serializer which allows this partial only update. We can see this for the UpdateModelMixin
:
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)
which calls update, which is:
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
return Response(serializer.data)
Upvotes: 1