在类中使用路由

时间:2017-06-27 12:06:14

标签: python flask

我试图将一些工作代码重写为一个类。

最小工作代码:

from flask import Flask

app = Flask(__name__)

@app.route("/1")
def func_1():
    return "view 1"

@app.route("/2")
def func_2():
    return "view 2"

app.run()

如何将其编写为具有在对象实例化期间定义的路径的类?

我只想要它干净:在实例化一个对象后,我希望相应的路由已经工作,没有额外的代码行。

这是我最接近的地方:

from flask import Flask

class NewView:

    def __init__(self, url, string):
        self.string = string
        self.server = Flask(__name__)
        self.server.add_url_rule(url, 'index', self.index)

    def index(self):
        return self.string

v1 = NewView("/1", "view 1")
v2 = NewView("/2", "view 2")

v1.server.run()

当然,这会将/1视为v1.index()的路由,但/2不起作用。

理想情况类似以下内容,但我无法使其发挥作用:

from flask import Flask

app = Flask(__name__)

class NewView:

    def __init__(self, url, string):
        ....
        app.add_url_rule(url, ...?..., self.index)

    def index(self):
        return self.string

v1 = NewView("/1", "view 1")
v2 = NewView("/2", "view 2")

app.run()

2 个答案:

答案 0 :(得分:1)

首先,你的错误:

def __init__(self, url, string):
    self.string = string
    self.server = Flask(__name__)
    self.server.add_url_rule(url, 'index', self.index)

因为你有这个类的两个实例,所以有两个Flask对象。你只运行第二个。

您可以立即尝试做的事情:

import flask

# There can be only one!
app = flask.Flask(__name__)


class MyView:
    def __init__(self, url, name, string):
        self.url = url
        self.string = string
        app.add_url_rule(url, name, self.serve)

    def serve(self):
        return self.string


view1 = MyView('/1', name='view1', string='This is View 1.')
view2 = MyView('/2', name='view2', string='This is View 2, not view 1.')

app.run()

上述代码可以正常工作并按预期执行。值得注意的是,由于Flask喜欢独特路线的名称,我让你为每条路线传递一个名字。这样,url_for('view1')url_for('view2')就可以了。

说了这么多,社区基本上已经完成了很多这个Pluggable Views。看看吧。

答案 1 :(得分:0)

我认为如果您的目标是保持代码清洁,则应避免创建从未使用过的对象。烧瓶中基于类的视图。正在传递的as_view()方法是类方法,所以这里也不需要创建一个从未使用过的对象。 registring urls的过程属于app的创建,而不是单独的对象(例如,它在Django中是如何工作的)。如果我是你,我会选择类似的东西:

from flask import Flask
from flask.views import View

def init_app():
    app = Flask(__name__)
    app.add_url_rule('/', view_func=NewView.as_view('index'))
    return app


class NewView(View):

    def dispatch_request(self):
        return 'Test'

app = init_app()
app.run()