Skip to main content

django-countdown

Tests Docs Python Version PyPI Version License

Display a maintenance countdown banner across a Django site, then block public access (returning HTTP 503) when the countdown expires. Superusers retain access during maintenance so they can finish the work and clear the countdown.

📖 Full documentation: https://iplweb.github.io/django-countdown/

Why?

Planned downtime is the worst kind of downtime to communicate badly. Users land on a half-broken page mid-deploy, hit error logs, file support tickets, and trust erodes. django-countdown lets you announce a maintenance window before it starts (a countdown banner with a real timer), then during the window swap public traffic for an explicit "we're in maintenance" page — while leaving operators unblocked so they can actually finish the work.

Features

  • Pre-maintenance banner — an ultra-visible countdown banner inserted into templates via context processor, with a JS timer that ticks live.
  • Hard cutoff at expiry — middleware returns HTTP 503 and renders a branded blocked page once the countdown lapses.
  • Superuser bypass — admins keep working through the cutoff so they can fix the underlying issue and clear the countdown.
  • Maintenance window — optional maintenance_until lets you set a target end-time; a second banner appears for superusers and the blocked page shows a live countdown to recovery.
  • Self-healing wait — the blocked page polls a status endpoint in the background and sends visitors back to the page they wanted the moment the site returns. It tells "still down for maintenance" apart from "nothing is answering while the container restarts", so a timer that runs out mid-deploy no longer strands anyone on the proxy's error page.
  • Per-Site configuration — uses Django's sites framework, so each domain in a multi-tenant setup has its own independent countdown.
  • A command per verb — start_countdown schedules a window, show_countdown reports where it stands (with --json for monitoring), extend_countdown and shorten_countdown move its boundaries when the plan slips, and stop_countdown reopens the site.
  • Dead man's switch — extend_countdown --at-least 5m raises a floor rather than adding time, so a deploy loop can hold the site closed while it works and let it reopen by itself if the deploy dies.
  • Admin integration — full Django admin support alongside the commands.

Supported versions

Django 3.10 3.11 3.12 3.13 3.14 Status
5.2 LTS ✓ ✓ ✓ ✓ ✓ Active LTS (extended support Apr 2028)
6.0 — — ✓ ✓ ✓ Mainstream Aug 2026, extended Apr 2027
6.1 — — ✓ ✓ ✓ Mainstream Apr 2027, extended Dec 2027

All 11 cells are exercised by the CI matrix on every push. Django is the only runtime dependency.

Installation

uv add django-countdown      # or: pip install django-countdown

Add the app, the middleware and the context processor to your settings:

INSTALLED_APPS = [
    # ...
    "django.contrib.sites",
    "django_countdown",
]
SITE_ID = 1

MIDDLEWARE = [
    # ...
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django_countdown.middleware.CountdownBlockingMiddleware",
]

TEMPLATES = [{
    # ...
    "OPTIONS": {"context_processors": [
        # ...
        "django_countdown.context_processors.countdown_context",
    ]},
}]

Then ./manage.py migrate, and include the banner in your base template:

{% include "django_countdown/countdown_banner.html" %}

Full walkthrough: Installation.

Quick start

./manage.py start_countdown --banner +15m --service +30m \
    --message "Database upgrade" --noinput

Banner shows for 15 minutes, then the site returns 503 for 30 minutes, then reopens by itself. Check on it with ./manage.py show_countdown, and reopen early with ./manage.py stop_countdown. Use --service indefinite to stay closed until you do. See Quickstart.

A working end-to-end example lives under example/.

Documentation

How it works The state machine, who sees what, failure behaviour
Countdown banner Including, styling and overriding the banner
Blocked page Three shipped variants and how to write your own
Scheduling a countdown Every option of start_countdown
Managing a running countdown show, stop, extend, shorten, and the deploy patterns
Multi-site setup One countdown per domain
Reference Settings, model, template context, template blocks

Development

git clone https://github.com/iplweb/django-countdown.git
cd django-countdown
uv sync --all-extras
uv run pytest

See Contributing.

License

MIT — see LICENSE for details.

Metadata

Release files for django-countdown 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-countdown 0.4.0
File Size Uploaded
django_countdown-0.4.0.tar.gz 63.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-countdown 0.4.0
File Interpreter ABI Platform
django_countdown-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 117.3 kB

Release files / django_countdown-0.4.0.tar.gz

Download URL django_countdown-0.4.0.tar.gz
Size 63.5 kB
Tags Source
SHA-256 checksum
How to use checksums
fc9e4d311ce2a08324ed3588d10f7bc423424f4a5581e8f826dee341c73a5f55
BLAKE2b-256 checksum
How to use checksums
badd6df46b3a8a160d8198ccc934acc510e5ec5a0367bab4a0a68efc3c80bb81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.

Transparency log

Release files / django_countdown-0.4.0-py3-none-any.whl

Download URL django_countdown-0.4.0-py3-none-any.whl
Size 53.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
44e2a15dcb173bdc34ae090deabb08ab97426a2ed000775cf5c9595e42806182
BLAKE2b-256 checksum
How to use checksums
a9d1e0122096b1898196f9425d5f528ed40bb6ba18654771e5f4d464780b728c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page