DRF mixin uses the model manager's create method but not the update method

# models.py
class HelloManager(models.Manager):
'''
On create, set date_created and last_modified to the same values
On update, set last_modified to current time
'''
def create(self, *args, **kwargs):
    current_time = datetime.now()
    kwargs.setdefault('date_created', current_time)
    kwargs.setdefault('last_modified', current_time)
    return super().create(*args, **kwargs)

def update(self, *args, **kwargs):
    kwargs['last_modified'] = datetime.now()
    return super().update(*args, **kwargs)

The CreateModelMixin works just fine, but the UpdateModelMixin does not call my manager's update method.

I went through DRF's implementation and found that the UpdateModelMixin calls serializer.save() wich calls either update or create but this is where I got lost.

I tried just directly overriding perform_create like so:

# views.py
class HelloDetailView(mixins.RetrieveModelMixin,
                      mixins.UpdateModelMixin,
                      generics.GenericAPIView):

queryset = HelloModel.objects.all()
lookup_field = 'id'

def get_serializer_class(self):
    if self.request.method == 'POST':
        return HelloWriteSerializer
    return HelloReadSerializer

def get(self, request, *args, **kwargs):
    return self.retrieve(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
    return self.update(request, *args, **kwargs)

def perform_update(self, serializer):
    HelloModel.objects.update(**serializer.validated_data)

But the problem now is the UpdateModelMixin now returns old data. What's the best approach for this?

I think you are not passing PK or ID in the update method like this:

def perform_update(self, serializer):
    instance = serializer.instance
    HelloModel.objects.update(pk=instance.pk, serializer.validated_data)

You should find the way to reload the instance into serializer after update.

def perform_update(self, serializer):
    HelloModel.objects.update(**serializer.validated_data)

    # reload instance into serializer after update
    updated_instance = HelloModel.objects.get(pk=serializer.instance.pk)
    serializer.instance = updated_instance
Back to Top