我想手动将路由定义为某些类的方法,如下所示:
class X:
def route1():
#do stuff here
def route2():
#do stuff here
然后做这样的事情:
app.add_url_rule('/x/', view_func=X.route1())
app.add_url_rule('/y/', view_func=X.route2())
可能吗?什么是正确的方法来实现这个目标?
答案 0 :(得分:10)
有几种方法可以做到这一点:
创建班级的全局实例并将规则路由到它:
class X(object):
# Your code here
INSTANCE_X = X()
# Note that we are not *calling* the methods
app.add_url_rule('/x/', view_func=INSTANCE_X.route1)
app.add_url_rule('/y/', view_func=INSTANCE_X.route2)
在视图函数中创建一个实例并委托给它:
# Using both methods of registering URLs here
# just to show that both work
@app.route('/x/')
def handle_route1():
return X().route1()
def handle_route2():
return X().route2()
app.add_url_rule('/y/', view_func=handle_route2)
继承Flask的View
或MethodView
Pluggable View课程并使用as_view
classmethod为您处理此问题:
class X(View):
methods = ['GET']
def dispatch_request(self):
if request.path == '/x/':
return route1()
elsif request.path == '/y/':
return route2()
else:
abort(404)
app.add_url_rule('/x/', view_func=X.as_view('X.route1'))
app.add_url_rule('/y/', view_func=X.as_view('X.route2'))
答案 1 :(得分:4)
就像我在评论中所说,你知道flask-classy吗?
从他们的例子来看:
from flask import Flask
from flask.ext.classy import FlaskView
# we'll make a list to hold some quotes for our app
quotes = [
"A noble spirit embiggens the smallest man! ~ Jebediah Springfield",
"If there is a way to do it better... find it. ~ Thomas Edison",
"No one knows what he can do till he tries. ~ Publilius Syrus"
]
app = Flask(__name__)
class QuotesView(FlaskView):
def index(self):
return "<br>".join(quotes)
def get(self, id):
id = int(id)
if id < len(quotes) - 1:
return quotes[id]
else:
return "Not Found", 404
QuotesView.register(app)
if __name__ == '__main__':
app.run()
会自动为http://foobar.foo/quotes
和http://foobar.foo/quotes/<id>
答案 2 :(得分:0)
如果您在谈论flask
的辅助装饰器app.route(...)
,请不要忘记,它只是一个装饰器,您总是可以call
的返回包装器装饰器。
使用像废话,无所事事的包装器
def some_wrapper():
def wrapper(fn):
return fn()
return wrapper
包裹类似的功能时,
@some_wrapper
def some_func():
print('Hello World')
出于所有意图和目的,可能正在发生的事情是
def some_func():
print('Hello World')
some_func = some_wrapper()(some_func)
因此,因此,您可以像任何装饰者一样调用app.route
,
app.route('/x/')(X.route1)
这与@ sean-vieira的回答-app.add_url_rule('/x/', view_func=INSTANCE_X.route1)
完全一样。
但是您可能更喜欢它的一个原因是,因为它遵循了烧瓶和烧瓶文档的“常规”路径。
对于我来说,使用它的原因是要链结一些我以编程方式添加的路线,
suffix = 'ducky'
app.route(f'secure_initial_route_for_{suffix}', endpoint=f'secure_{suffix}')(
roles_required('admin')(secured_fn))
app.route(f'secure_sub_route_for_{suffix}', endpoint=f'secure_sub_{suffix}')(
roles_required('admin')(secured_sub_fn))
这就是我的一些用例。