Как обновить тело Django HttpRequest в промежуточном программном обеспечении

У меня есть запрос PUT, и я хочу обновить значения нескольких параметров в своем промежуточном программном обеспечении. Я знаю, что нет прямого доступа к параметрам PUT, поэтому я обращаюсь к ним через request.body.

Как только эти значения будут обновлены, мне нужно передать это request в представление. Однако, если я попытаюсь сделать:

request.body = new_content

в моем промежуточном программном обеспечении я получаю:

AttributeError: can't set attribute

Есть ли способ обновить эти параметры в промежуточном программном обеспечении и передать их?


person sparknoob    schedule 30.03.2014    source источник


Ответы (1)


request.body определяется как property в HttpRequest.

Это код, как выглядит свойство body:

@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")
        try:
            self._body = self.read()
        except IOError as e:
            six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()[2])
        self._stream = BytesIO(self._body)
    return self._body

Подход, который я буду использовать, заключается в изменении атрибута _body в process_request< /а> метод. Возвращаемое значение здесь равно None, потому что я хочу, чтобы Django продолжал обрабатывать этот запрос через промежуточное ПО до соответствующего представления.

class MidddlewareWithHttpPutRequest:
    def process_request(self, request):
        data = getattr(request, '_body', request.body)
        request._body = data + '&dummy_param=1'
        # if you call request.body here you will see that new parameter is added
        return None
person P̲̳x͓L̳    schedule 30.03.2014
comment
Чтобы добавить к этому примечание: request.body вызовет request.read(), который читает из файлового буфера request._stream. Мне также нужно было пополнить этот буфер (Django Rest Framework читает из этого буфера). Вы можете сделать это request._stream = BytesIO(body_contents) - person Jacob Valenta; 24.04.2014