使用Flask手动定义路线

时间:2014-11-28 16:41:05

标签: python flask

我想手动将路由定义为某些类的方法,如下所示:

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())

可能吗?什么是正确的方法来实现这个目标?

3 个答案:

答案 0 :(得分:10)

有几种方法可以做到这一点:

  1. 创建班级的全局实例并将规则路由到它:

    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)
    
  2. 在视图函数中创建一个实例并委托给它:

    # 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)
    
  3. 继承Flask的ViewMethodView 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/quoteshttp://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))

这就是我的一些用例。