6.2.1. Built-in converters
When you define a route in Flask, you can specify parts of it that will be converted into Python variables and passed to the view function.
def profile(username): pass
Whatever is in the part of the URL labeled
<username> will get passed
to the view as the username argument. You can also specify a converter
to filter the variable before it's passed to the view.
def profile(user_id): pass
In this code block, the URL http://myapp.com/user/id/Q29kZUxlc3NvbiEh will return a 404 status code - not found. This is because the part of the URL that is supposed to be an integer is actually a string.
We could have a second view that looks for a string as well. That would be called for /user/id/Q29kZUxlc3NvbiEh/ while the first would be called for /user/id/124.
This table shows Flask's built-in URL converters.
||Accepts any text without a slash (the default).|
||Like int but for floating point values.|
||Like string but accepts slashes.|
6.2.2. Custom converters
We can also make custom converters to suit our needs. On Reddit — a popular link sharing site — users create and moderate communities for theme-based discussion and link sharing. Some examples are /r/python and /r/flask, denoted by the path in the URL: reddit.com/r/python and reddit.com/r/flask respectively. An interesting feature of Reddit is that you can view the posts from multiple subreddits as one by seperating the names with a plus-sign in the URL, e.g. reddit.com/r/python+flask.
We can use a custom converter to implement this feature in our own Flask
apps. We'll take an arbitrary number of elements separated by
plus-signs, convert them to a list with a
ListConverter class and pass
the list of elements to the view function.
# myapp/util.py from werkzeug.routing import BaseConverter class ListConverter(BaseConverter): def to_python(self, value): return value.split('+') def to_url(self, values): return '+'.join(BaseConverter.to_url(value) for value in values)
We need to define two methods:
to_url(). As the
to_python() is used to convert the path in the URL to a
Python object that will be passed to the view and
to_url() is used by
url_for() to convert arguments to their appropriate forms in the URL.
To use our
ListConverter, we first have to tell Flask that it exists.
# /myapp/__init__.py from flask import Flask app = Flask(__name__) from .util import ListConverter app.url_map.converters['list'] = ListConverter
Caution This is another chance to run into some circular import problems if
util module has a
from . import app line. That's why I waited
until app had been initialized to import
Now we can use our converter just like one of the built-ins. We
specified the key in the dictionary as "list" so that's how we use it
# myapp/views.py from . import app def subreddit_home(subreddits): """Show all of the posts for the given subreddits.""" posts =  for subreddit in subreddits: posts.extend(subreddit.posts) return render_template('/r/index.html', posts=posts)
This should work just like Reddit's multi-reddit system. This same method can be used to make any URL converter we can dream of.