Tackling Django 1.11's RawPostDataException

You cannot access body after reading from request's data stream  

So Django's request.body is apparently a stream now, which means it can be only accessed once.

Relevant docs:

Code just in case it's moved or removed:

def read(self, *args, **kwargs):  
        self._read_started = True
            return self._stream.read(*args, **kwargs)
        except IOError as e:
            six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()

So as listed, if _read_started is set to True, it won't let you read again. So, you either need to make sure you don't access this data in the middleware or don't access it above in the same code hierarchy.

Best way to tackle this?

Add an attribute to the request object in the middleware where you can access it right at the beginning.

import six

class MyRequestModifyingMiddleware(object):

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):

        def some_other_operation(data):
            return data

        def proces_request(request):
            # do stuff here
            request.MY_NEW_KEY = some_other_operation(copy_body(request))

        def copy_body(request):
            data = getattr(request, '_body', request.body)
            request._body = data
            # why six? Because that's where django gets its exception
            request._stream = six.BytesIO(data)
            request._files = None
            return data 

        return self.get_response(request)

So in the deeper sections of your code, you can simply access request.MY_NEW_KEY.

Gist showing how to manipulate request object

How to write your own middleware Django 1.11