Search code examples
djangopython-3.6django-middleware

Modify value of body in django request


I want to update the value of the json body value in a post Request in my django API (also using rest framework), right now I'm trying to doing this with a custom middleware. This is my middleware.

def CustomMiddleware(get_response):
    def middleware(request):

        print('request: ', request, ' type: ', type(request), ' vars: ', vars(request))
        print('request: ', request.body)
        body = json.loads(request.body)
        body['attr'] = str(body['attr'])+'abc'
        request.body = json.dumps(body)
        response = get_response(request)
        return response

return middleware

So when I'm doing a POST request to my API, I got this error:

File "/path/models_masking/mask_middleware.py", line 37, in middleware
    request.body = json.dumps(request_updated)
AttributeError: can't set attribute

I'd reading and discovered that the request object is immutable, so I'm not sure if I'm able to copy to request object, modify the copy and then sent it to the get_response function, or maybe there's a better approach to do this, maybe a decorator for my APIView classes.

Could anybody help me out with an elegant solution for this?

EDIT

The value of 'attr'+'abc' is a new value that is used in a lot of parts of the codebase, my core problem is that I don't want to alter that value in a lot of functions that are in a lot of request endpoints, so my first idea was to update the value of the requests to change value of 'attr' automatically in all of the requests, instead of update each one.

This maybe could be a new question, but if anyone could give a better solution for my problem, i would be thankful.


Solution

  • I agree with other people it's not common to alter the body of the request, but if you really need to, then you can set request._body since body is just a property

        @property
        def body(self):
            if not hasattr(self, '_body'):
                if self._read_started:
                    raise RawPostDataException("You cannot access body after reading from request's data stream")
    
                # Limit the maximum request data size that will be handled in-memory.
                if (settings.DATA_UPLOAD_MAX_MEMORY_SIZE is not None and
                        int(self.META.get('CONTENT_LENGTH') or 0) > settings.DATA_UPLOAD_MAX_MEMORY_SIZE):
                    raise RequestDataTooBig('Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.')
    
                try:
                    self._body = self.read()
                except IOError as e:
                    raise UnreadablePostError(*e.args) from e
                self._stream = BytesIO(self._body)
            return self._body