2017-05-22 47 views
1

我有Django的1.10项目及以下用户定义的中间件编辑响应contect

class RequestLogMiddleWare(object): 
    def __init__(self, get_response): 
     self.get_response = get_response 

    def __call__(self, request): 
     response = self.get_response(request) 
     response.data['detail'] = 'I have been edited' 
     return response 

和REST的端点观点:

def r_mobile_call_log(request): 
    return Response({'success': True, 
        'detail': 'Before having been edited'}, 
         status=status.HTTP_200_OK) 

,所以我期望的最终响应客户端是:

{'success': 'True', 'detail': 'I have been edited'} 

不过,我看到的是:

{'success': 'True', 'detail': 'Before having been edited'} 

我在中间件的调用方法中放置了一个断点,以确保该函数真正执行,并且没关系。 response.data["details"]只是不会改变它的价值。任何人都知道这是什么原因? 预先感谢您

回答

3

Response已经呈现在中间件阶段,因此您不能只更改response.data,您需要重新渲染它或直接更改呈现的内容。

class RequestLogMiddleWare(object): 
    def __init__(self, get_response): 
     self.get_response = get_response 

    def __call__(self, request): 
     response = self.get_response(request) 
     if isinstance(response, Response): 
      response.data['detail'] = 'I have been edited' 
      # you need to change private attribute `_is_render` 
      # to call render second time 
      response._is_rendered = False 
      response.render() 
     return response 

第二种方法只是改变的内容直接,但在这种情况下,建于REST框架的浏览器的API将无法工作,因为模板无法正常显示。

import json 

class RequestLogMiddleWare(object): 
    def __init__(self, get_response): 
     self.get_response = get_response 

    def __call__(self, request): 
     response = self.get_response(request) 
     if isinstance(response, Response): 
      response.data['detail'] = 'I have been edited' 
      response.content = json.dumps(response.data) 
     return response 

source code for render method

0

我有一种感觉,我发现了清晰的解决方案。以下是我重写代码的方式:

class RequestLogMiddleWare(object): 
def __init__(self, get_response): 
    self.get_response = get_response 
    def __call__(self, request): 
     response = self.get_response(request) 

    def process_template_response(self, request, response): 
     if hasattr(response, 'data'): 
      response.data['detail'] = 'bla-bla-bla' 
     return response