2017-06-27 3 views
0

Ich versuche, einige Arbeitscode als eine Klasse neu zu schreiben.Verwenden von Routen in Klassen

Ein minimaler Arbeitscode:

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

Wie es als eine Klasse mit der Strecke während des Objektinstanziierung definiert schreiben?

Ich möchte es nur sauber: nach der Instantiierung eines Objekts möchte ich die entsprechende Route bereits ohne zusätzliche Codezeilen arbeiten.

Dies ist das nächste, was ich zu bekommen:

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

Das ist natürlich erkennt /1 als Weg für v1.index(), aber /2 funktioniert nicht.

Das Ideal wäre etwa wie folgt sein, aber ich kann es nicht funktioniert:

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

Ich denke, was Sie wollen, ist hier dokumentiert http://flask.pooco.org/docs/0.12/views/ - mit 'add_url_rule' außerhalb der Klasse und' app.add_url_rule ('/ 1', view_func = NewView .as_view ('index')) 'vielleicht? –

+0

@Simon Fraser, ja, das ist eine Möglichkeit, aber ich möchte alle innerhalb der Klasse "enthalten", um den Code sauber zu halten, add_url_rule enthalten. Ich kann keinen direkten Weg finden, es zu tun. –

Antwort

1

Zuerst Ihr Fehler:

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

Weil Sie zwei Instanzen dieser Klasse haben, gibt es zwei Fläschchen Objekte. Du läufst nur den zweiten.

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

Das funktioniert und über Code tun, was Sie erwarten:

Was Sie sofort zu tun versuchen können, wie dies getan werden. Etwas zu beachten ist, dass, da Flask Namen für einzigartige Routen mag, habe ich Sie für jede Route einen Namen eingeben. Auf diese Weise funktionieren url_for('view1') und url_for('view2').

Nachdem all dies gesagt wurde, hat die Community bereits viel von diesem Pluggable Views erreicht. Hör zu.

+0

Danke, Ken Kinder. –

0

Ich denke, dass, wenn Ihr Ziel Code sauber zu halten, sollten Sie Erstellen von Objekten vermeiden, die nie verwendet werden. Die klassenbasierten Ansichten in flask. Die as_view()-Methode, die übergeben wird, ist die Klassenmethode. Daher ist es auch hier nicht erforderlich, ein nie verwendetes Objekt zu erstellen. Der Prozess des Registrierens von URLs gehört zur Erstellung einer App, nicht zu separaten Objekten (so funktioniert es zum Beispiel in Django). Wenn ich Sie wäre, würde ich mit etwas Ähnliches gehen:

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

werden die Objekte tatsächlich verwendet. Ich habe nur alle nicht-sinnvollen Teile entfernt, um das Beispiel zu entfernen. Jedes Objekt in meinem Fall ist ein Bokeh-Diagramm. Für jede gibt es eine Route, um eine Datenaktualisierung anzufordern. Ich verstehe, was du meinst mit ** der Prozess der Registrierung von URLs gehört zur Erstellung einer App **, aber ich dachte, es ist möglich, dynamisch eine neue Route für jedes instanziierte Objekt hinzufügen die URL als Parameter in __init__ übergeben. Danke –

Verwandte Themen