FlaskはURLルーティングで正規表現をサポートしていますか?


100

Flaskにはint、float、およびpathコンバーターがあることを理解していますが、私たちが開発しているアプリケーションのURLにはより複雑なパターンがあります。

Djangoのように、正規表現を使用する方法はありますか?

回答:


192

アーミンは受け入れられた答えで私を殴りましたが、誰かがこれを行う方法の実用的な例を望んでいる場合に備えて、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

1
これは、正規表現が実行時に直接評価されるように見えます。最後の2、3の正規表現パターンはメモリにコンパイルされて保存されるため、これは小さなアプリ(または正規表現を複数回再利用するアプリ)では問題にならないはずです。
bbenne10 2013

5
これはどのように作動しますか?パターンはに設定されてself.regexいますが、一致はどこで発生しますか?
ジャスティン

@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

また、catch allタイプのルートを記述して、メソッド内で複雑なルーティングを行うこともできます。

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()

これはどのリクエストにも一致します。詳細はこちら:キャッチオールURL


エラーが発生しました。手がかりを教えてください。ファイル「/app/catch_all.py」、行234、<モジュール> @ 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 '既存のエンドポイント関数:%s'%エンドポイント)AssertionError:ビュー関数マッピングが既存のエンドポイント関数を上書きしています:テスト
スパーク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.