Flask는 URL 라우팅에서 정규식을 지원합니까?


100

Flask에는 int, float 및 path 변환기가 있지만 우리가 개발중인 응용 프로그램의 URL에는 더 복잡한 패턴이 있다는 것을 이해합니다.

장고처럼 정규 표현식을 사용할 수있는 방법이 있습니까?

답변:


192

Armin이 받아 들여진 대답으로 나를 펀치로 이겼지 만 누군가가 어떻게 할 수 있는지에 대한 실제 예제를 원할 경우 Flask에서 정규식 매처를 구현 한 방법에 대한 축약 된 예를 보여줄 것이라고 생각했습니다.

from flask import Flask
from werkzeug.routing import BaseConverter

app = Flask(__name__)

class RegexConverter(BaseConverter):
    def __init__(self, url_map, *items):
        super(RegexConverter, self).__init__(url_map)
        self.regex = items[0]


app.url_map.converters['regex'] = RegexConverter

@app.route('/<regex("[abcABC0-9]{4,6}"):uid>-<slug>/')
def example(uid, slug):
    return "uid: %s, slug: %s" % (uid, slug)


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)

이 URL은 200 : http : // localhost : 5000 / abc0-foo / 와 함께 반환되어야합니다 .

이 URL은 404 : http : // localhost : 5000 / abcd-foo / 와 함께 반환되어야합니다 .


4
그러나 이것은 정규식이 컴파일된다는 의미입니까, 아니면 즉석에서 평가됩니까?
Games Brainiac 2013-07-13

1
정규식이 런타임에 직접 평가되는 것처럼 보입니다. 마지막 몇 개의 정규식 패턴이 메모리에 컴파일되어 저장되므로 작은 앱 (또는 정규식을 여러 번 재사용하는 앱)에서는 문제가되지 않습니다.
bbenne10

5
어떻게 작동합니까? 패턴이로 설정되어 self.regex있지만 일치는 어디에서 발생합니까?
Justin

@Justin 매칭은 Werkzeug의 내부에서 발생합니다. 여기 와 내가 찾지 못한 규칙의 정의 어딘가에 있습니다.
AlexLordThorsen 2016

49

임의의 식과 일치하는 사용자 지정 변환기를 연결할 수 있습니다. 사용자 지정 변환기

from random import randrange
from werkzeug.routing import Rule, Map, BaseConverter, ValidationError

class BooleanConverter(BaseConverter):

    def __init__(self, url_map, randomify=False):
        super(BooleanConverter, self).__init__(url_map)
        self.randomify = randomify
        self.regex = '(?:yes|no|maybe)'

    def to_python(self, value):
        if value == 'maybe':
            if self.randomify:
                return not randrange(2)
            raise ValidationError()
        return value == 'yes'

    def to_url(self, value):
        return value and 'yes' or 'no'

url_map = Map([
    Rule('/vote/<bool:werkzeug_rocks>', endpoint='vote'),
    Rule('/vote/<bool(randomify=True):foo>', endpoint='foo')
], converters={'bool': BooleanConverter})

내가 무엇을 이해하지 to_python않습니다
corvid

17

캐치 모든 유형의 경로를 작성하고 메소드 내에서 복잡한 라우팅을 수행 할 수도 있습니다.

from flask import Flask
app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'], defaults={'path': ''})
@app.route('/<path:path>', methods=['GET', 'POST'])
def catch_all(path):
    return 'You want path: %s' % path

if __name__ == '__main__':
    app.run()

이것은 모든 요청과 일치합니다. 자세한 내용은 Catch-All URL을 참조하세요 .


오류가 있습니다. 단서를 좀 알려주시겠습니까? 파일 "/app/catch_all.py", 234 행, <module> @ app.route ( '/ <path : path>', methods = [ 'GET']) 파일 "/ usr / local / lib / python2. 7 / dist-packages / flask / app.py ", 라인 1080, 데코레이터 파일"/usr/local/lib/python2.7/dist-packages/flask/app.py ", 라인 64, wrapper_func 파일"/ usr / local / lib / python2.7 / dist-packages / flask / app.py ", 1051 행, add_url_rule 'existing endpoint function : % s'% endpoint) AssertionError : View function mapping is overwriting the existing endpoint function : test
Spark
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.