Jak używać adresu url, jeśli moja metoda ma wiele adnotacji do trasy?

Więc mam metodę, która jest dostępna wieloma trasami:

@app.route("/canonical/path/")
@app.route("/alternate/path/")
def foo():
    return "hi!"
Jak mogę zadzwonić i wiedzieć, że dostanę pierwszą trasę?
Author: jiggy, 2011-10-16

3 answers

Ok. Trzeba było trochę zagłębić się w kod werkzeug.routing i flask.helpers.url_for, ale rozgryzłem to. Po prostu zmień endpoint dla trasy (innymi słowy, ty Nazwa Twoja trasa)

@app.route("/canonical/path/", endpoint="foo-canonical")
@app.route("/alternate/path/")
def foo():
    return "hi!"

@app.route("/wheee")
def bar():
    return "canonical path is %s, alternative is %s" % (url_for("foo-canonical"), url_for("foo"))

Wyprodukuje

Canonical path is / canonical / path/, alternative is / alternate / path /

Istnieje pewna wada tego podejścia. Flask zawsze wiąże ostatnią zdefiniowaną trasę z punktem końcowym zdefiniowanym domyślnie (foo w kodzie). Zgadnij, co się stanie, jeśli przedefiniujesz punkt końcowy? Wszystkie twoje url_for('old_endpoint') rzucą werkzeug.routing.BuildError. Więc, myślę, że właściwym rozwiązaniem dla całego problemu jest zdefiniowanie ścieżki kanonicznej ostatniej i Nazwa alternatywa:

""" 
   since url_for('foo') will be used for canonical path
   we don't have other options rather then defining an endpoint for
   alternative path, so we can use it with url_for
"""
@app.route('/alternative/path', endpoint='foo-alternative')
""" 
   we dont wanna mess with the endpoint here - 
   we want url_for('foo') to be pointing to the canonical path
"""
@app.route('/canonical/path') 
def foo():
    pass

@app.route('/wheee')
def bar():
    return "canonical path is %s, alternative is %s" % (url_for("foo"), url_for("foo-alternative"))
 73
Author: Nemoden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-29 16:54:17

Zasady w kolbie są unikalne. Jeśli zdefiniujesz absolutny ten sam adres URL do tej samej funkcji, domyślnie będzie to kolidować, ponieważ robisz coś, co powstrzymujemy Cię od robienia, ponieważ z naszej perspektywy jest to złe.

Istnieje jeden powód, dla którego chcesz mieć więcej niż jeden adres URL do tego samego punktu końcowego i jest to wsteczna zgodność z regułą, która istniała w przeszłości. Od WZ0. 8 i Flask 0.8 można jawnie określić alias dla trasa:

@app.route('/')
@app.route('/index.html', alias=True)
def index():
    return ...

W tym przypadku, jeśli użytkownik zażąda /index.html Flask automatycznie wyda stałe przekierowanie do just /.

Nie oznacza to jednak, że funkcja nie może być powiązana z więcej niż jednym adresem url, ale w tym przypadku trzeba by zmienić punkt końcowy:

@app.route('/')
def index():
    ...

app.add_url_rule('/index.html', view_func=index, endpoint='alt_index')

Lub alternatywnie:

@app.route('/')
@app.route('/index.html', endpoint='alt_index')
def index():
    ...

W tym przypadku można zdefiniować Widok po raz drugi pod inną nazwą. Jednak jest to coś, czego generalnie chcesz uniknąć, ponieważ wtedy widok funkcja musiałaby sprawdzić żądanie.punkt końcowy, aby zobaczyć, co się nazywa. Zamiast tego lepiej zrób coś takiego:

@app.route('/')
def index():
    return _index(alt=False)

@app.route('/index.html')
def alt_index():
    return _index(alt=True)

def _index(alt):
    ...

W obu tych przypadkach generowanie adresu URL to url_for('index') lub url_for('alt_index').

Można to również zrobić na poziomie systemu routingu:

@app.route('/', defaults={'alt': False})
@app.route('/index.html', defaults={'alt': True})
def index(alt):
    ...

W tym przypadku generowanie adresu url to url_for('index', alt=True) lub url_for('index', alt=False).

 51
Author: Armin Ronacher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-24 13:07:50

Dodatkowo, dla tych, którzy używają trasy catch all zbudowanej ze zmiennych: Flask poprawnie utworzy ścieżkę url, jeśli url_for zostanie przekazany słownik zawierający zmienne.

Na przykład...

App.py:

app.route('/<path:pattern1>')
app.route('/<path:pattern1>/<path:pattern2>')
def catch_all(pattern1, pattern2=None):
    return render_template('template.html', p1=pattern1, p2=pattern2)

app.route('/test')
def test_routing:
    args = {'pattern1': 'Posts', 'pattern2': 'create'}
    return render_template('test.html', args=args)

Test.html:

<a href="{{url_for('catch_all', **args)}}">click here</a>

Po kliknięciu na link 'Kliknij tutaj' zostaniesz przekierowany do trasy' Posts/create'.

 1
Author: vincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 21:57:34