在Django中间件中编辑响应内容 [英] Editing response content in Django middleware

查看:232
本文介绍了在Django中间件中编辑响应内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有Django 1.10项目和以下用户定义的中间件

I have Django 1.10 project and the following user-defined middleware

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)

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

So I would expect the final response on client-side to be:

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

但是,我看到的是:

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

我在中间件的 call 方法中设置了一个断点确保该函数确实已执行,并且可以。 response.data [ details] 只是不会更改其值。有人知道这是什么原因吗?

I put a breakpoint in the middleware's call method to make sure that the function really is executed, and it's ok. response.data["details"] just won't change it's value. Anyone knows what's the reason for this ?

推荐答案

响应已经呈现在中间件阶段,您不仅可以更改 response.data ,还需要重新渲染或直接更改渲染的内容。

Response is already rendered in the middleware stage so you can't just change response.data, you need to rerender it or change rendered content directly.

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 Framework浏览器API无法正常工作,因为模板无法正确呈现。

The second approach is to change content directly, but in that case builtin REST Framework browser API will not work because template will not render properly.

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

渲染方法的源代码

这篇关于在Django中间件中编辑响应内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆