59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
"""
|
|
utils.converter: Custom URL converters to match patterns in @app.route()
|
|
|
|
The Flask documentation is elusive on this topic. To add a new converter,
|
|
proceed as follows:
|
|
|
|
1. Define a new converter class.
|
|
2. Set the [regex] attribute to decide which portion of the URL will be
|
|
considered for conversion (apparently the default is everything until next
|
|
slash or end of string).
|
|
3. Define the to_python() and to_url() methods to actually convert.
|
|
4. Add the class to __all__ at the bottom of this file.
|
|
5. In app/__init__.py, add a dictionary entry to [app.url_map.converters].
|
|
|
|
For more information, see the Werkzeug documentation:
|
|
<https://werkzeug.palletsprojects.com/en/0.15.x/routing/#custom-converters>
|
|
"""
|
|
|
|
from werkzeug.routing import BaseConverter, ValidationError
|
|
from app.models.forum import Forum
|
|
from app.models.topic import Topic
|
|
import re
|
|
import sys
|
|
|
|
class ForumConverter(BaseConverter):
|
|
|
|
# This regex will decide which portion of the URL is matched by the curtom
|
|
# converter. By default, slashes are not included, so we must add them.
|
|
regex = r'[a-z/]+'
|
|
|
|
def to_python(self, url):
|
|
url = '/' + url
|
|
f = Forum.query.filter_by(url=url).first()
|
|
if f is None:
|
|
raise ValidationError(f"ForumConverter: no forum with url {url}")
|
|
return f
|
|
|
|
def to_url(self, forum):
|
|
return forum.url[1:]
|
|
|
|
class TopicSlugConverter(BaseConverter):
|
|
|
|
# Only catch integers followed by an optional slug string
|
|
regex = r'(\d+)(?:-[\w-]*)?'
|
|
|
|
def to_python(self, url):
|
|
"""Convert an URL pattern to a Python object, or raise an exception."""
|
|
m = re.fullmatch(TopicSlugConverter.regex, url)
|
|
if m is None:
|
|
raise Exception(f"TopicSlugConverter: conversation failed")
|
|
|
|
return Topic.query.get_or_404(int(m[1], 10))
|
|
|
|
def to_url(self, topic):
|
|
return str(topic.id)
|
|
|
|
# Export only the converter classes
|
|
__all__ = "ForumConverter TopicSlugConverter".split()
|