根据Flask.make_response方法的Flask文档,允许从视图返回的唯一类型是app.response_class,str,unicode,wsgi函数或具有响应对象的元组的实例以下之一。
我希望能够从视图中返回我自己的模型和查询,并使通用代码构建适当的响应,将对象序列化为可接受的格式,从查询构建集合,应用过滤条件等。哪个地方最适合这个?
我考虑了以下几种可能性,但无法找到正确的方法。
edit1 :我已经有许多API,我需要在视图中实现这些行为,但我希望避免在任何地方重复这些行为。
edit2 :我实际构建了一个Flask-extension,其中包含我的应用程序中使用的许多默认实践。虽然一个普通的装饰工作肯定会起作用,但我真的需要更多的魔法。
答案 0 :(得分:3)
为什么不创建一个函数make_response_from_custom_object
并以
return make_response_from_custom_object(custom_object)
如果它会变得很普遍,我会将它放入@response_from_custom_object
装饰器中,但挂钩到Flask似乎有点矫枉过正。你可以链接装饰器,所以包装app.route
也没有意义;你需要的只是
@app.route(..)
@response_from_custom_object
def view(...):
...
如果你能以简单明了的方式做到这一点,那么就没有必要让你的代码变得神奇,因此不易理解。
答案 1 :(得分:1)
您走的链越远(make_response
,dispatch_request
+ handle_user_error
,full_dispatch_request
,rewrite Flask from scratch
)您需要恢复的功能越多创建
在这种情况下最简单的方法是覆盖response_class
并在那里进行序列化 - 这将为您留下Flask在make_response
,full_dispatch_request
等中所做的所有魔力,但仍然可以控制如何响应异常和序列化响应。它还保留了Flask的所有挂钩,因此您的扩展程序的使用者可以覆盖他们需要的行为(并且他们可以重用他们现有的Flask请求/生命周期知识)
答案 2 :(得分:0)
Python本质上是动态的,因此虽然这不是最佳实践,但您可以将应用程序上的make_response
方法重新分配给所需的内容。
为避免重新创建默认功能,您可以保存对原始功能的引用,并使用该引用来实现新功能。
我最近在项目中使用了此功能,以添加直接从烧瓶视图返回自定义Serializable
类实例的功能。
app = Flask("StarCorp")
__original_make_response = app.make_response
def convert_custom_object(obj):
# Check if the returned object is "Serializable"
if not isinstance(obj, Serializable):
# Nope, do whatever flask normally does
return __original_make_response(obj)
# It is, get a `dict` from `obj` using the `json` method
data = obj.json
data.pop(TYPE_META) # Don't share the type meta info of an object with users
# Let flask turn the `dict` into a `json` response
return __original_make_response(data)
app.make_response = convert_custom_object
由于flask扩展通常提供init_app(app)
方法,因此我确信您可以构建一个扩展,以类似的方式让猴子修补传入的应用程序对象。