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