Jak mohu použít url_for jestli moje metoda má několik popisů trasy?

hlasů
36

Takže mám metodu, která je přístupná několika cestami:

@app.route(/canonical/path/)
@app.route(/alternate/path/)
def foo():
    return hi!

Nyní, jak mohu zavolat url_for(foo)a vím, že jsem se dostat na první cestu?

Položena 16/10/2011 v 03:49
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
59

OK. Trvalo nějaký ponoří do werkzeug.routinga flask.helpers.url_forkódu, ale já jsem přišel. Jen změníte endpointna trase (jinými slovy, název trasy)

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

bude vyrábět

kanonický cesta je / kanonické / cesta /, alternativou je / alternativní / cesta /

Tam je nevýhodou tohoto přístupu. Baňka vždy váže naposledy definovaný cestu do koncového bodu dané implicitně ( foov kódu). Odhadnout, co se stane, pokud předefinovat koncový bod? Všechny vaše url_for('old_endpoint')bude hodit werkzeug.routing.BuildError. Takže, myslím, že tím pravým řešením pro celé problematice je definování kanonických dráhu poslední a jméno alternativu:

""" 
   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"))
Odpovězeno 17/10/2011 v 14:32
zdroj uživatelem

hlasů
48

Pravidla v baňce jsou jedinečné. Pokud definujete absolutní stejnou adresu URL pro stejnou funkci, bude ve výchozím nastavení střet, protože děláte něco, co vás zastavit od toho, protože z našeho pohledu, který je v pořádku.

K dispozici je jeden z důvodů, proč byste chtěli mít více než jednu adresu URL na absolutní stejný koncový bod, a to je zpětná kompatibilita s pravidlem, které existovaly v minulosti. Vzhledem k tomu, WZ0.8 a Baňka 0,8 můžete explicitně aliasu pro trasy:

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

V tomto případě, pokud uživatel požaduje /index.htmlBaňky budou automaticky vydávat trvale přesměrovat jen /.

To neznamená, že funkce nemůže být vázán na více než jednu adresu URL i když, ale v tomto případě budete muset změnit koncový bod:

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

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

Nebo alternativně:

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

V tomto případě můžete definovat zaměřením podruhé pod jiným názvem. Nicméně toto je něco, co obvykle chceme vyhnout, protože pak funkce pohled bude muset zkontrolovat request.endpoint aby zjistili, co se říká. Místo toho raději něco takového:

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

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

def _index(alt):
    ...

V obou těchto případech generace URL url_for('index')nebo url_for('alt_index').

Můžete si také udělat na úrovni směrování systému:

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

V tomto případě generování url url_for('index', alt=True)nebo url_for('index', alt=False).

Odpovězeno 24/10/2011 v 14:07
zdroj uživatelem

hlasů
0

Navíc pro ty, kteří využívají úlovek všechny trasy konstruovány s proměnnými: Baňky bude správně vytvořit cestu URL, pokud url_forje předán slovník, který obsahuje proměnné.

Například...

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>

Když kliknete na odkaz ‚klikněte sem‘, budete přesměrováni na ‚Příspěvky / vytvoření‘ cestou.

Odpovězeno 24/03/2015 v 21:57
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more