django-countdown¶
Announce planned Django downtime before it starts, then close the site cleanly while it happens — without locking yourself out.
django-countdown gives you two things that work together:
- A countdown banner injected into your own templates, with a live JS timer counting down to the moment the site closes.
- A blocking middleware that returns
HTTP 503and renders a branded maintenance page once that moment arrives — except for superusers, who keep browsing so they can finish the work.
Everything is driven by a single database row per
Site, which
you create from the Django admin or with one command:
$ ./manage.py start_countdown --banner +15m --service +30m \
--message "Database upgrade" --noinput
✓ Created countdown for example.com.
There is a command for every other verb too — because the moment you need them, the site is usually already closed and the plan is already slipping:
$ ./manage.py show_countdown # which phase, and how long left?
$ ./manage.py extend_countdown # it is taking longer than planned
$ ./manage.py shorten_countdown # it is going faster
$ ./manage.py stop_countdown # done — reopen the site
Why it exists¶
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. Announcing the window in advance and serving an honest 503 during it turns an incident into a non-event.
Features¶
-
Pre-maintenance banner
An ultra-visible banner with a timer that ticks live, injected through a context processor and included wherever you want it.
-
Hard cutoff at expiry
Middleware returns
HTTP 503and renders a maintenance page the moment the countdown lapses — a status code that proxies and crawlers understand. -
Superuser bypass
Admins keep working through the cutoff so they can finish the job and clear the countdown.
-
Bounded or indefinite windows
Set
maintenance_untilfor auto-recovery, or leave it empty to stay blocked until someone explicitly unblocks. -
Per-Site configuration
One countdown per domain via
django.contrib.sites— multi-tenant projects close one site without touching the rest. -
Translatable
Every user-visible string goes through
gettext; English and Polish catalogs ship with the package.
Where to go next¶
| I want to… | Read |
|---|---|
| Install and wire it into settings | Installation |
| See a countdown running in three minutes | Quickstart |
| Understand who sees what, and when | How it works |
| Restyle the maintenance page | Blocked page |
| Script downtime from CI or a deploy hook | Scheduling a countdown |
| Check on, adjust or end a window already running | Managing a running countdown |
| Look up a field, setting or template block | Reference |
Requirements¶
| Django | 3.10 | 3.11 | 3.12 | 3.13 | 3.14 |
|---|---|---|---|---|---|
| 5.2 LTS | ✓ | ✓ | ✓ | ✓ | ✓ |
| 6.0 | — | — | ✓ | ✓ | ✓ |
| 6.1 | — | — | ✓ | ✓ | ✓ |
All eleven cells run in CI on every push. The only runtime dependency is Django itself.
Licence¶
MIT — see LICENSE.