2011-10-16 5 views
35

तो मैं एक विधि है कि कई मार्गों से पहुँचा जा सकता है है:यदि मेरी विधि में एकाधिक रूट एनोटेशन हैं तो मैं url_for का उपयोग कैसे करूं?

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

अब, मैं कैसे url_for("foo") फोन और पता है कि मैं पहली बार मार्ग मिल जाएगा कर सकते हैं?

उत्तर

58

ठीक है। इसने werkzeug.routing और flask.helpers.url_for कोड में कुछ हल किया, लेकिन मुझे पता चला है। तुम बस मार्ग के लिए endpoint बदल (दूसरे शब्दों में, आप नाम अपने मार्ग)

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

का उत्पादन करेगा

विहित पथ/है विहित/path/वैकल्पिक/वैकल्पिक/मार्ग है/

इस दृष्टिकोण की कमी है। फ्लास्क हमेशा अंतिम परिभाषित मार्ग को अंतिम बिंदु पर परिभाषित करता है जो आपके कोड में स्पष्ट रूप से परिभाषित होता है (foo)। मान लें कि क्या होता है यदि आप एंडपॉइंट को फिर से परिभाषित करते हैं? आपके सभी url_for('old_endpoint')werkzeug.routing.BuildError फेंक देंगे। तो, मुझे लगता है कि पूरे मुद्दे के लिए सही समाधान विहित पथ पिछले और नाम निर्धारित है विकल्प:

फ्लास्क में
""" 
    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")) 
+1

क्या एक संपूर्ण और सुंदर जवाब है। मुझे सत्यापित करने का मौका दें और मैं इसे स्वीकार कर दूंगा। आपको इसे पोको लोगों को सबमिट करना चाहिए ताकि इसे आधिकारिक रूप से दस्तावेज किया जा सके। – jiggy

+0

ठीक है, तब तक इसमें कुछ परेशानी थी जब तक कि मैं फ्लास्क 0.8 में अपग्रेड नहीं हुआ (यह 0.7.2 के साथ विफल रहा)। ऐसा लगता है कि यह पहली टिप्पणी नहीं है, न कि मेरे लिए आखिरी। किसी भी तरह से, एंडपॉइंट परम कुंजी है। – jiggy

48

नियम अद्वितीय हैं। यदि आप एक ही फ़ंक्शन पर पूर्ण यूआरएल को परिभाषित करते हैं तो यह डिफ़ॉल्ट रूप से संघर्ष करेगा क्योंकि आप ऐसा कुछ कर रहे हैं जो हम आपको हमारे परिप्रेक्ष्य से गलत होने के बाद से करने से रोकते हैं।

एक कारण है कि आप एक ही अंतराल पर एक से अधिक यूआरएल रखना चाहते हैं और यह अतीत में मौजूद नियम के साथ पिछड़ा संगतता है। इस मामले में

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

उपयोगकर्ता /index.html बोतल स्वचालित रूप से एक स्थायी रूप से बस / को अनुप्रेषित जारी करेगा अनुरोध करता है, तो: WZ0.8 और बोतल 0.8 जब से तुम स्पष्ट रूप से एक मार्ग के लिए एक उपनाम निर्दिष्ट कर सकते हैं।

कि एक समारोह मतलब यह नहीं है, हालांकि एक से अधिक यूआरएल के लिए बाध्य नहीं किया जा सकता, लेकिन इस मामले में आप अंत बिंदु को बदलने की जरूरत होगी:

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

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

या वैकल्पिक रूप से:

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

इस मामले में आप एक अलग नाम के तहत दूसरी बार एक दृश्य परिभाषित कर सकते हैं। हालांकि यह ऐसा कुछ है जिसे आप आम तौर पर टालना चाहते हैं क्योंकि दृश्य कार्य को अनुरोध करने के लिए request.endpoint को देखना होगा। इसके बजाय बेहतर कर कुछ इस तरह:

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

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

def _index(alt): 
    ... 

इन मामलों यूआरएल पीढ़ी के दोनों में url_for('index') या url_for('alt_index') है।

तुम भी मार्ग प्रणाली के स्तर पर कर सकते हैं:

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

इस मामले यूआरएल पीढ़ी में url_for('index', alt=True) या url_for('index', alt=False) है।

+0

यह दस्तावेज़ीकरण में होना अच्छा लगेगा (या यह पहले से ही है? नहीं मिला)। आपका आखिरी उदाहरण बिल्कुल मेरे लिए जरूरी था। – aplavin

0

इसके अतिरिक्त, चर के साथ बनाए गए सभी मार्गों को पकड़ने वाले लोगों के लिए: url_for को चर के साथ एक शब्दकोष पारित किया गया है, तो फ्लास्क सही ढंग से यूआरएल पथ बना देगा।

उदाहरण के लिए ...

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> 

आप 'यहाँ क्लिक करें' लिंक पर क्लिक करने पर आपको निर्देशित किया जाएगा 'पोस्ट/बनाएं' मार्ग पर।

संबंधित मुद्दे

 संबंधित मुद्दे