Python 从Flask视图返回任意对象

Python 从Flask视图返回任意对象,python,flask,Python,Flask,根据该方法的Flask文档,允许从视图返回的唯一类型是app.response_类、str、unicode、wsgi函数的实例,或响应对象已在上述之一之后的元组 我希望能够从视图中返回我自己的模型和查询,并使用通用代码构建适当的响应,将对象序列化为可接受的格式,从查询中构建集合,应用过滤条件,等等。哪里是连接的最佳位置 我考虑了以下几种可能性,但无法找到一种正确的方法 子类化响应并设置app.Response\u类 子分类烧瓶重新定义烧瓶。做出响应 将app.route包装到另一个装饰器中 在

根据该方法的Flask文档,允许从视图返回的唯一类型是app.response_类、str、unicode、wsgi函数的实例,或响应对象已在上述之一之后的元组

我希望能够从视图中返回我自己的模型和查询,并使用通用代码构建适当的响应,将对象序列化为可接受的格式,从查询中构建集合,应用过滤条件,等等。哪里是连接的最佳位置

我考虑了以下几种可能性,但无法找到一种正确的方法

  • 子类化响应并设置app.Response\u类
  • 子分类烧瓶重新定义烧瓶。做出响应
  • 将app.route包装到另一个装饰器中
  • 在你要求之后
  • ?
edit1:我已经有了许多API,这些API具有我需要在视图中实现的行为,但我希望避免在任何地方重复这些行为


edit2:实际上,我正在使用应用程序中使用的许多默认实践构建一个Flask扩展。虽然一个普通的装饰器肯定会起作用,但我真的需要比这更神奇的一点。

为什么不从自定义对象创建一个函数
make\u response\u
,并以

return make_response_from_custom_object(custom_object)
如果它很常见,我会把它放在一个来自定制对象装饰器的
@响应中,但挂在烧瓶里似乎是一种过度的行为。您可以链接装饰程序,因此包装
app.route
也没有意义;你所需要的只是

@app.route(..)
@response_from_custom_object
def view(...):
    ...

如果你能以简单明了的方式来做,那么让你的代码变魔术从而变得不易理解是没有意义的。

你越往上走(
做出响应
发送请求
+
处理用户错误
完整发送请求
从头重写烧瓶
)需要重新创建的功能越多


在这种情况下,最简单的方法是重写
response\u类
并在那里进行序列化-这让您拥有Flask在
make\u response
full\u dispatch\u request
等中所做的所有魔术,但仍然可以控制如何响应异常和序列化响应。它还保留了Flask的所有钩子,因此扩展的使用者可以在需要的地方重写行为(并且他们可以重用他们对Flask的请求/生命周期的现有知识)

Python本质上是动态的,所以虽然这可能不是最佳实践,您可以将应用程序上的
make_response
方法重新分配给您想要的任何对象

为了避免重新创建默认功能,可以保存对原始函数的引用,并使用该引用实现新函数

我最近在一个项目中使用它来添加直接从flask视图返回自定义
Serializable
类实例的功能

app=Flask(“StarCorp”)
__原始\u生成\u响应=app.make\u响应
def convert_自定义_对象(obj):
#检查返回的对象是否“可序列化”
如果不存在(对象,可序列化):
#不,做烧瓶通常做的事
返回原始响应(obj)
#也就是说,使用'json'方法从'obj'获取'dict'
data=obj.json
data.pop(TYPE_META)#不与用户共享对象的TYPE META信息
#让flask将'dict'转换为'json'响应
返回原始响应(数据)
app.make\u response=转换\u自定义\u对象

由于flask扩展通常提供一个
init_app(app)
方法,因此我确信您可以构建一个扩展,以类似的方式对传入的应用程序对象进行monkey修补。

这当然是一个有效的解决方案,但实际上我需要做这件事。我正在编写一个Flask扩展,它遵循我的团队所采用的模式和实践,以便正确地记录行为。我们更喜欢在后台发生一些神奇的事情,但是事情按照我们想要的方式进行,而不是手工操作。如果你在看烧瓶扩展,为什么不研究一下它们是如何处理序列化的呢?我已经做过了。Flask Untivent自动创建视图,并对所有视图应用装饰器。我不会自动处理视图,所以这对我来说不起作用。无论如何,谢谢你。