如何在Middleware中更新Django HttpRequest主体

spa*_*oob 6 python django middleware httprequest

我有一个PUT请求,我想更新我的中间件中的一些参数的值.我知道没有办法直接访问PUT参数,所以我通过它访问它们request.body.

一旦更新了这些值,我需要将其传递request给视图.但是,如果我尝试这样做:

request.body = new_content
Run Code Online (Sandbox Code Playgroud)

在我的中间件中,我得到:

AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)

有没有办法更新中间件中的这些参数并传递它们?

P̲̳*_*͓L̳ 11

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
Run Code Online (Sandbox Code Playgroud)

我将在那里使用_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
Run Code Online (Sandbox Code Playgroud)

  • 要为此添加注释:request.body将调用request.read(),它从类似文件的缓冲区`request._stream`中读取.我也需要"重新填充"这个缓冲区(Django Rest Framework从这个缓冲区中读取).您可以通过`request._stream = BytesIO(body_contents)`来实现 (3认同)