Was ist ein Endpunkt in Flask?

124

Die Kolbendokumentation zeigt :

add_url_rule(*args, **kwargs)
      Connects a URL rule. Works exactly like the route() decorator.
      If a view_func is provided it will be registered with the endpoint.

     endpoint  the endpoint for the registered URL rule. Flask itself assumes the name of the view function as endpoint

Was genau ist mit einem "Endpunkt" gemeint?

Fuziang
quelle

Antworten:

267

So funktioniert das Flask Routing

Die gesamte Idee von Flask (und der zugrunde liegenden Werkzeug-Bibliothek) besteht darin, URL-Pfade einer Logik zuzuordnen, die Sie ausführen werden (normalerweise die "Ansichtsfunktion"). Ihre Grundansicht ist wie folgt definiert:

@app.route('/greeting/<name>')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

Beachten Sie, dass die Funktion, auf die Sie verwiesen haben (add_url_rule), dasselbe Ziel erreicht, nur ohne die Dekorationsnotation zu verwenden. Daher ist Folgendes dasselbe:

# No "route" decorator here. We will add routing using a different method below.
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

app.add_url_rule('/greeting/<name>', 'give_greeting', give_greeting)

Angenommen, Ihre Website befindet sich unter "www.example.org" und verwendet die obige Ansicht. Der Benutzer gibt die folgende URL in seinen Browser ein:

http://www.example.org/greeting/Mark

Die Aufgabe von Flask besteht darin, diese URL zu übernehmen, herauszufinden, was der Benutzer tun möchte, und sie zur Verarbeitung an eine Ihrer vielen Python-Funktionen weiterzuleiten. Es nimmt den Weg :

/greeting/Mark

... und ordnet es der Routenliste zu. In unserem Fall haben wir diesen Pfad definiert, um zumgive_greeting Funktion zu gelangen.

Dies ist zwar die typische Methode zum Erstellen einer Ansicht, abstrahiert jedoch einige zusätzliche Informationen von Ihnen. Hinter den Kulissen hat Flask den Sprung nicht direkt von der URL zur Ansichtsfunktion geschafft, die diese Anforderung verarbeiten sollte. Es heißt nicht einfach ...

URL (http://www.example.org/greeting/Mark) should be handled by View Function (the function "give_greeting")

Tatsächlich gibt es einen weiteren Schritt, bei dem die URL einem Endpunkt zugeordnet wird:

URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "give_greeting".
Requests to Endpoint "give_greeting" should be handled by View Function "give_greeting"

Grundsätzlich ist der "Endpunkt" eine Kennung, mit der bestimmt wird, welche logische Einheit Ihres Codes die Anforderung verarbeiten soll . Normalerweise ist ein Endpunkt nur der Name einer Ansichtsfunktion. Sie können den Endpunkt jedoch tatsächlich ändern, wie im folgenden Beispiel beschrieben.

@app.route('/greeting/<name>', endpoint='say_hello')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

Wenn Flask die Anforderung weiterleitet, sieht die Logik folgendermaßen aus:

URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "say_hello".
Endpoint "say_hello" should be handled by View Function "give_greeting"

So verwenden Sie den Endpunkt

Der Endpunkt wird üblicherweise für die "umgekehrte Suche" verwendet. In einer Ansicht Ihrer Flask-Anwendung möchten Sie beispielsweise auf eine andere Ansicht verweisen (möglicherweise, wenn Sie von einem Bereich der Site zu einem anderen verlinken). Anstatt die URL fest zu codieren, können Sie sie verwenden url_for(). Nehmen Sie Folgendes an

@app.route('/')
def index():
    print url_for('give_greeting', name='Mark') # This will print '/greeting/Mark'

@app.route('/greeting/<name>')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

Dies ist vorteilhaft, da wir jetzt die URLs unserer Anwendung ändern können, ohne die Zeile ändern zu müssen, in der wir auf diese Ressource verweisen.

Warum nicht einfach immer den Namen der Ansichtsfunktion verwenden?

Eine Frage, die auftauchen könnte, ist die folgende: "Warum brauchen wir diese zusätzliche Schicht?" Warum einen Pfad einem Endpunkt und dann einen Endpunkt einer Ansichtsfunktion zuordnen? Warum nicht einfach diesen mittleren Schritt überspringen?

Der Grund ist, dass es auf diese Weise mächtiger ist. Zum Beispiel Flask Blueprints können Sie Ihre Anwendung in verschiedene Teile aufteilen. Möglicherweise befinden sich alle Ressourcen auf der Administratorseite in einem Entwurf mit dem Namen "admin" und alle Ressourcen auf Benutzerebene auf einem Endpunkt mit dem Namen "user".

Mit Blaupausen können Sie diese in Namespaces unterteilen. Beispielsweise...

main.py:

from flask import Flask, Blueprint
from admin import admin
from user import user

app = Flask(__name__)
app.register_blueprint(admin, url_prefix='admin')
app.register_blueprint(user, url_prefix='user')

admin.py:

admin = Blueprint('admin', __name__)

@admin.route('/greeting')
def greeting():
    return 'Hello, administrative user!'

user.py:

user = Blueprint('user', __name__)
@user.route('/greeting')
def greeting():
    return 'Hello, lowly normal user!'

Beachten Sie, dass in beiden Bauplänen die Route '/ greeting' eine Funktion namens "greeting" ist. Wenn ich auf die Administrator-Begrüßungsfunktion verweisen wollte, konnte ich nicht einfach "Begrüßung" sagen, da es auch eine Benutzer-Begrüßungsfunktion gibt. Endpunkte ermöglichen eine Art Namespace, indem Sie den Namen der Blaupause als Teil des Endpunkts angeben. Also könnte ich folgendes tun ...

print url_for('admin.greeting') # Prints '/admin/greeting'
print url_for('user.greeting') # Prints '/user/greeting'
Mark Hildreth
quelle
1
Wie wäre es mit url_forroot? Ich habe einen Fehler festgestelltCould not build url for endpoint ''
TomSawyer
Ihre Erklärung hat mir sehr gut gefallen und mir eine gute Vorstellung davon gegeben, wie diese Endpunkte funktionieren. Jetzt, da ich dieses Konzept verstehe, fehlt Ihnen jedoch ein Punkt in Bezug auf die Endpunkte, insbesondere in Flask. Wenn Sie die Endpunkte nicht angeben, kann Ihre Regel in der url_for()Funktion durch Ändern des Namens einer Funktion / Klasse aus X- oder Y-Gründen verletzt werden (jemand hat den Code überarbeitet und einen passenderen Namen gefunden usw.). Die automatisch generierten Endpunkte von Flask helfen Ihnen bei der Bearbeitung der URL-Änderungen. Der explizite Endpunkt hilft Ihnen beim Umgang mit URL- und Namensänderungen Ihrer Funktion.
IMCoins
1
Dies verdeutlicht mein Verständnis der Endpunktfunktionalität von Flask und vielleicht sogar der Definition des Endpunkts im Allgemeinen. Auch ich habe Tippfehler gefunden. Sollte Ihre Ansichtsfunktion nicht give_greetingstattdessen sein my_greeting? Ich my_greeting
sehe
23

Endpunkt ist der Name, mit dem die URL-Regeln rückwärts gesucht werden, url_forund standardmäßig der Name der Ansichtsfunktion.

Kleines Beispiel:

from flask import Flask, url_for

app = Flask(__name__)

# We can use url_for('foo_view') for reverse-lookups in templates or view functions
@app.route('/foo')
def foo_view():
    pass

# We now specify the custom endpoint named 'bufar'. url_for('bar_view') will fail!
@app.route('/bar', endpoint='bufar')
def bar_view():
    pass

with app.test_request_context('/'):
    print url_for('foo_view')
    print url_for('bufar')
    # url_for('bar_view') will raise werkzeug.routing.BuildError
    print url_for('bar_view')
plaes
quelle