2011-10-16 4 views

답변

58

확인. werkzeug.routingflask.helpers.url_for 코드로 일부 검색이 완료되었지만 알아 냈습니다. 당신은 단지

정식 경로가 정식/경로//입니다

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

생산됩니다 (당신이 이름 경로, 즉) 경로에 대한 endpoint 변경, 대안/대체/경로는/

이 접근법의 단점이 있습니다. Flask는 항상 마지막으로 정의 된 경로를 암시 적으로 정의 된 끝점에 바인딩합니다 (코드에서 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

철저하고 근사한 대답. 나에게 확인할 수있는 기회를 줘 보자. pocoo 사람들에게 이것을 제출하여 공식적으로 문서화해야합니다. – jiggy

+0

좋아, 내가 술병 0.8로 업그레이드 할 때까지 이것으로 약간의 문제가 있었다 (0.7.2로 실패했다). 그것은 또한 첫 번째 주석을 포착하는 것이지, 나에게는 마지막 것이 아닙니다. 어쨌든, 끝점 매개 변수가 핵심입니다. – jiggy

48

규칙은 고유 : 그래서, 나는 모든 문제에 적합한 솔루션이 마지막과 이름을 대안을 정식 경로를 정의하는 것 같아요. 동일한 함수에 절대적으로 동일한 URL을 정의하면 기본적으로 충돌합니다. 왜냐하면 우리가 바라는 관점에서 잘못한 일을하기 때문에 무언가를하고 있기 때문입니다.

절대 엔드 포인트에 둘 이상의 URL이 있고 과거에 존재했던 규칙과의 하위 호환성이있는 이유 중 하나가 있습니다. WZ0.8와 플라스 0.8 이후로 명시 적 경로에 대한 별칭을 지정할 수 있습니다

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

을이 경우 사용자가 플라스크가 자동으로 영구적 단지 /로 리디렉션 발급 /index.html 요청합니다. 함수를 의미하지 않는다

하지만 하나 개 이상의 URL에 바인딩 될 수 있지만,이 경우 당신은 엔드 포인트 변경해야 :

@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를 확인해야하기 때문에 일반적으로 피해야 할 사항입니다. 이 같은 대신 더 나은 무언가 : 이러한 경우의 URL 생성 모두에

@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')이다.

또한 라우팅 시스템 레벨에서이 작업을 수행 할 수 있습니다 :이 경우 URL이 생성에서

@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

또한 변수로 구성된 모든 경로를 캐치하는 경우 : Flask는 url_for에 변수가 포함 된 사전이 전달되면 URL 경로를 올바르게 만듭니다. 예를 들어

...

은 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> 

, 당신은 이동합니다 '작성/작성'경로로 이동하십시오.