You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask-RESTX中使用response_ok时添加HTTP响应头的解决方案

解决Flask-RESTX自定义装饰器无法处理make_response生成的Response对象问题

问题核心在于marshal_with默认只处理视图函数返回的原始数据(如字典、模型对象),而make_response返回的是封装好的Response实例,装饰器无法自动识别并处理其中的响应数据。以下是两种实用解决方案:

方案1:修改装饰器兼容Response对象

直接在自定义装饰器中判断返回值类型,若为Response则提取数据进行marshal,再重新封装并保留原响应头:

from flask import Response, make_response
from flask_restx import marshal

def response_ok(model):
    def decorator(func):
        def wrapper(*args, **kwargs):
            result = func(*args, **kwargs)
            
            if isinstance(result, Response):
                # 提取Response中的JSON数据
                raw_data = result.get_json()
                # 对原始数据执行marshal操作
                marshaled_data = marshal(raw_data, model)
                # 重新生成Response,保留原状态码和响应头
                new_resp = make_response(marshaled_data, result.status_code)
                new_resp.headers = result.headers
                return new_resp
            # 非Response类型直接marshal处理
            return marshal(result, model)
        return wrapper
    return decorator

使用示例:

from flask import make_response
from your_module import response_ok, your_model

@response_ok(your_model)
def test_view():
    raw_data = {"id": 1, "name": "demo"}
    resp = make_response(raw_data)
    resp.headers["X-Custom-Token"] = "abc123"
    return resp

方案2:统一由装饰器封装响应

调整视图函数返回格式,让装饰器负责生成Response对象,同时支持自定义响应头:

from flask import make_response
from flask_restx import marshal

def response_ok(model):
    def decorator(func):
        def wrapper(*args, **kwargs):
            result = func(*args, **kwargs)
            
            # 解析视图返回的不同格式:数据、(数据, 状态码)、(数据, 响应头)、(数据, 状态码, 响应头)
            data = result
            status_code = 200
            headers = {}
            
            if isinstance(result, tuple):
                if len(result) == 2:
                    if isinstance(result[1], int):
                        data, status_code = result
                    else:
                        data, headers = result
                elif len(result) == 3:
                    data, status_code, headers = result
            
            # 执行marshal并生成最终Response
            marshaled_data = marshal(data, model)
            return make_response(marshaled_data, status_code, headers)
        return wrapper
    return decorator

使用示例:

@response_ok(your_model)
def test_view():
    raw_data = {"id": 1, "name": "demo"}
    headers = {"X-Custom-Token": "abc123"}
    # 直接返回数据和响应头,由装饰器处理marshal和Response封装
    return raw_data, headers

两种方案对比:

  • 方案1适合已有大量使用make_response的旧代码,最小改动即可兼容;
  • 方案2更符合Flask-RESTX的设计规范,统一响应封装逻辑,减少重复代码。

内容的提问来源于stack exchange,提问作者cassham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:32:08