Plain is headed towards 1.0! Subscribe for development updates →

plain.redirection

A flexible URL redirection system with admin interface and logging.

Overview

plain.redirection provides a database-driven URL redirection system for Plain applications. It includes:

  • Database models for managing redirects
  • Middleware that intercepts 404s and checks for matching redirects
  • Support for both exact matches and regex patterns
  • Comprehensive logging of redirects and 404s
  • Built-in admin interface for managing redirects

Basic Usage

Setting up the middleware

Add the RedirectionMiddleware to your middleware stack in settings.py:

MIDDLEWARE = [
    # ... other middleware ...
    "plain.redirection.RedirectionMiddleware",
    # This should typically be near the end of the middleware stack
]

Creating redirects

You can create redirects programmatically using the Redirect model:

from plain.redirection.models import Redirect

# Simple path redirect
Redirect.objects.create(
    from_pattern="/old-page/",
    to_pattern="/new-page/",
    http_status=301  # Permanent redirect
)

# Redirect with different status code
Redirect.objects.create(
    from_pattern="/temporary-page/",
    to_pattern="/replacement-page/",
    http_status=302  # Temporary redirect
)

Advanced Features

Regex redirects

For more complex URL patterns, you can use regex redirects:

# Redirect all blog posts to a new URL structure
Redirect.objects.create(
    from_pattern=r"^/blog/(\d{4})/(\d{2})/(.+)/$",
    to_pattern=r"/posts/\1-\2-\3/",
    is_regex=True,
    http_status=301
)

Redirect ordering

When multiple redirects might match a URL, you can control which one takes precedence using the order field:

# This redirect will be checked first (lower order = higher priority)
Redirect.objects.create(
    from_pattern="/special-case/",
    to_pattern="/handled-specially/",
    order=10
)

# This more general redirect will be checked later
Redirect.objects.create(
    from_pattern=r"^/special-.*/$",
    to_pattern="/general-handler/",
    is_regex=True,
    order=20
)

Logging

The package automatically logs all redirects and 404s:

  • RedirectLog - Records successful redirects with request metadata
  • NotFoundLog - Records 404s that didn't match any redirect

Access logs programmatically:

from plain.redirection.models import RedirectLog, NotFoundLog

# Recent redirects
recent_redirects = RedirectLog.objects.all()[:10]

# 404s from a specific IP
not_founds = NotFoundLog.objects.filter(ip_address="192.168.1.1")

Admin Interface

The package includes admin views for managing redirects and viewing logs. Once installed, you'll find three new sections in your admin:

  • Redirects - Create, edit, and delete redirect rules
  • Redirect logs - View successful redirects with full request details
  • 404 logs - Monitor URLs that resulted in 404s

The admin interface is automatically registered and will appear in the "Redirection" section of your Plain admin.

Installation

Install the plain.redirection package from PyPI:

uv add plain.redirection