Co to jest „punkt końcowy” w Flask?

125

Dokumentacja Flask pokazuje :

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

Co dokładnie oznacza „punkt końcowy”?

Fuziang
źródło

Odpowiedzi:

267

Jak działa routing Flask

Cała idea Flaska (i podstawowej biblioteki Werkzeug) polega na mapowaniu ścieżek URL do jakiejś logiki, którą będziesz uruchamiać (zazwyczaj jest to „funkcja widoku”). Twój podstawowy widok jest zdefiniowany w następujący sposób:

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

Zwróć uwagę, że funkcja, o której wspomniałeś (add_url_rule) osiąga ten sam cel, tylko bez użycia notacji dekoratora. Dlatego następujące jest to samo:

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

Załóżmy, że Twoja witryna znajduje się pod adresem „www.example.org” i korzysta z powyższego widoku. Użytkownik wprowadza następujący adres URL do swojej przeglądarki:

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

Zadaniem Flaska jest pobranie tego adresu URL, ustalenie, co chce zrobić użytkownik, i przekazanie go do obsługi jednej z wielu funkcji Pythona. Obejmuje ścieżkę :

/greeting/Mark

... i dopasowuje go do listy tras. W naszym przypadku zdefiniowaliśmy tę ścieżkę, aby przejść do give_greetingfunkcji.

Jednak chociaż jest to typowy sposób tworzenia widoku, w rzeczywistości pobiera od Ciebie dodatkowe informacje. Za kulisami Flask nie wykonał skoku bezpośrednio z adresu URL do funkcji widoku, która powinna obsłużyć to żądanie. Nie mówi po prostu ...

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

Właściwie jest jeszcze jeden krok, w którym mapuje adres URL do punktu końcowego:

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"

Zasadniczo „punkt końcowy” to identyfikator używany do określania, która jednostka logiczna kodu powinna obsłużyć żądanie . Zwykle punkt końcowy to po prostu nazwa funkcji widoku. Jednak w rzeczywistości można zmienić punkt końcowy, tak jak w poniższym przykładzie.

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

Teraz, gdy Flask kieruje żądanie, logika wygląda następująco:

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"

Jak używasz punktu końcowego

Punkt końcowy jest powszechnie używany do „wyszukiwania wstecznego”. Na przykład w jednym widoku aplikacji Flask chcesz odwołać się do innego widoku (być może podczas łączenia z jednego obszaru witryny do innego). Zamiast na stałe zakodować adres URL, możesz użyć url_for(). Załóżmy, co następuje

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

Jest to korzystne, ponieważ teraz możemy zmienić adresy URL naszej aplikacji bez konieczności zmiany wiersza, w którym odwołujemy się do tego zasobu.

Dlaczego po prostu nie zawsze używać nazwy funkcji widoku?

Pytanie, które może się pojawić, brzmi: „Dlaczego potrzebujemy tej dodatkowej warstwy?” Po co mapować ścieżkę do punktu końcowego, a następnie punkt końcowy do funkcji widoku? Dlaczego po prostu nie pominąć tego środkowego kroku?

Powodem jest to, że w ten sposób jest silniejszy. Na przykład Flask Blueprints umożliwiają podzielenie aplikacji na różne części. Mogę mieć wszystkie moje zasoby po stronie administratora w planie o nazwie „admin”, a wszystkie zasoby na poziomie użytkownika w punkcie końcowym o nazwie „użytkownik”.

Schematy umożliwiają rozdzielenie ich na przestrzenie nazw. Na przykład...

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!'

Zauważ, że w obu planach trasa „/ powitanie” jest funkcją zwaną „powitaniem”. Gdybym chciał odnieść się do funkcji „pozdrowienia” administratora, nie mógłbym po prostu powiedzieć „pozdrowienia”, ponieważ istnieje również funkcja „powitanie” użytkownika. Punkty końcowe pozwalają na pewien rodzaj przestrzeni nazw, określając nazwę planu jako część punktu końcowego. Mogłem więc wykonać następujące czynności ...

print url_for('admin.greeting') # Prints '/admin/greeting'
print url_for('user.greeting') # Prints '/user/greeting'
Mark Hildreth
źródło
1
Co powiesz url_forna rootowanie? Could not build url for endpoint ''
Złapałem
Naprawdę podobało mi się twoje wyjaśnienie i dało mi to niezły pomysł na to, jak działają te punkty końcowe. Jednak teraz, gdy rozumiem tę koncepcję, myślę, że brakuje ci punktu dotyczącego punktów końcowych, szczególnie w Flasku. Jeśli nie określisz punktów końcowych, twoja reguła w url_for()funkcji może zostać złamana przez zmianę nazwy funkcji / klasy z powodów X lub Y (ktoś przeredagował kod i znalazł bardziej odpowiednią nazwę itp.). Punkty końcowe generowane automatycznie przez Flask ułatwiają obsługę zmian adresu URL. Jawny punkt końcowy pomaga radzić sobie ze zmianami adresu URL i zmianą nazwy funkcji.
IMCoins,
1
To naprawdę wyjaśnia moje rozumienie funkcji punktów końcowych Flask, a może nawet ogólnej definicji punktu końcowego. Znalazłem też literówkę. Czy nie powinna być give_greetingzamiast tego funkcja View my_greeting? Nigdzie nie widzę my_greeting...
steveohmn
23

Punkt końcowy to nazwa używana do wyszukiwania wstecznego reguł adresu URL z url_fori domyślnie jest to nazwa funkcji widoku.

Mały przykład:

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
źródło