Here is what I did to solve it, although it would be nice if there was a more general way to do this, since it is such a common URL pattern. First I created a mixin for my ViewSets, which overrided the create method:
class CreatePartialModelMixin(object): def initial_instance(self, request): return None def create(self, request, *args, **kwargs): instance = self.initial_instance(request) serializer = self.get_serializer( instance=instance, data=request.DATA, files=request.FILES, partial=True) if serializer.is_valid(): self.pre_save(serializer.object) self.object = serializer.save(force_insert=True) self.post_save(self.object, created=True) headers = self.get_success_headers(serializer.data) return Response( serializer.data, status=status.HTTP_201_CREATED, headers=headers) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
It is basically copied and pasted from CreateModelMixin , but it defines an initial_instance method that we can override in subclasses to provide a starting point for a serializer that is configured for partial deserialization. Then I can do, for example,
class SubObjectViewSet(CreatePartialModelMixin, viewsets.ModelViewSet):
(I understand that I really do not need to do .get on pk to associate it with the model, but in my case, I open slug, not the primary key in the public API)
source share