python 38 lines · 6 steps

Custom URL converters in Flask

A custom slug converter validates and normalizes URL segments before your view functions ever run.

Explained by highlit
1from werkzeug.routing import BaseConverter, ValidationError
2from flask import Flask, jsonify, abort
3 
4 
5class SlugConverter(BaseConverter):
6 regex = r"[a-z0-9]+(?:-[a-z0-9]+)*"
7 
8 def to_python(self, value):
9 if len(value) > 200:
10 raise ValidationError()
11 return value
12 
13 def to_url(self, value):
14 slug = value.strip().lower().replace(" ", "-")
15 return super().to_url(slug)
16 
17 
18app = Flask(__name__)
19app.url_map.converters["slug"] = SlugConverter
20 
21 
22@app.route("/articles/<slug:slug>")
23def show_article(slug):
24 article = Article.query.filter_by(slug=slug).first()
25 if article is None:
26 abort(404)
27 return jsonify(article.to_dict())
28 
29 
30@app.route("/categories/<slug:category>/<slug:slug>")
31def show_in_category(category, slug):
32 article = (
33 Article.query
34 .join(Category)
35 .filter(Category.slug == category, Article.slug == slug)
36 .first_or_404()
37 )
38 return jsonify(article.to_dict())
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A converter's regex filters requests at the routing layer, so bad URLs never reach your view.
  2. 2to_python and to_url let you validate incoming segments and normalize outgoing ones symmetrically.
  3. 3Registering a converter by name makes it reusable across every route as <name:variable>.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Custom URL converters in Flask — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code