Flask の URL ルーティングでは <int:id> のようなコンバータを使える。独自のコンバータを作成すれば、URL パラメータの検証や変換を一元化できる。
組み込みコンバータ
Flask には以下のコンバータが組み込まれている。
| string | デフォルト。スラッシュを含まない文字列 |
| int | 正の整数 |
| float | 正の浮動小数点数 |
| path | スラッシュを含む文字列 |
| uuid | UUID 文字列 |
| any | 指定した値のいずれか |
カスタムコンバータの作成
werkzeug.routing.BaseConverter を継承して作成する。
from werkzeug.routing import BaseConverter
class RegexConverter(BaseConverter):
def __init__(self, map, regex):
super().__init__(map)
self.regex = regex
# アプリケーションに登録
app.url_map.converters['regex'] = RegexConverter
@app.route('/user/<regex("[a-z]+"):username>')
def user_profile(username):
return f'User: {username}'
値の変換を行うコンバータ
to_python で URL から Python オブジェクトへ、to_url で Python オブジェクトから URL へ変換する。
from werkzeug.routing import BaseConverter
from datetime import date
class DateConverter(BaseConverter):
regex = r'\d{4}-\d{2}-\d{2}'
def to_python(self, value):
# URL パラメータを date オブジェクトに変換
return date.fromisoformat(value)
def to_url(self, value):
# date オブジェクトを URL 文字列に変換
return value.isoformat()
app.url_map.converters['date'] = DateConverter
@app.route('/events/<date:event_date>')
def event(event_date):
# event_date は date オブジェクト
return f'Event on {event_date.strftime("%B %d, %Y")}'
url_for 使用時に to_url が呼ばれる。
url_for('event', event_date=date(2024, 12, 25))
# '/events/2024-12-25'
リストを受け取るコンバータ
class ListConverter(BaseConverter):
regex = r'[\w,]+'
def to_python(self, value):
return value.split(',')
def to_url(self, values):
return ','.join(values)
app.url_map.converters['list'] = ListConverter
@app.route('/tags/<list:tags>')
def filter_by_tags(tags):
# tags はリスト ['python', 'flask', 'api']
return f'Tags: {tags}'
モデルを直接取得するコンバータ
class UserConverter(BaseConverter):
regex = r'\d+'
def to_python(self, value):
user = User.query.get(int(value))
if user is None:
raise ValidationError('User not found')
return user
def to_url(self, user):
return str(user.id)
app.url_map.converters['user'] = UserConverter
@app.route('/profile/<user:user>')
def profile(user):
# user は User オブジェクト
return f'Profile: {user.name}'
カスタムコンバータを活用すれば、ルーティング層でバリデーションや変換を完結させ、ビュー関数をシンプルに保てる。