django-adr
A Django reusable package to manage Architectural Decision Records (ADR).
Requires Python 3.12 or newer and Django 5.2 LTS or newer. Every supported combination — Python 3.12/3.13/3.14 against Django 5.2/6.0/6.1 — is exercised by the test suite on every push.
Features
- Django Admin interface to create and manage ADRs
- HTML list and detail views with status filtering
- Read-only REST API (Django REST Framework) with pre-rendered Markdown HTML fields
- Management command
create_adrto create ADRs from the CLI, with optional--supersedesto mark an existing ADR as superseded in one step - Management command
export_adrsto export all ADRs as Markdown files - Markdown support for context, decision, and consequences fields
- Internationalization (i18n) support — English locale included
Installation
pip install django-adr
Add to INSTALLED_APPS:
INSTALLED_APPS = [
...
"django_adr",
]
Include the URLs:
from django.urls import include, path
urlpatterns = [
...
path("adrs/", include("django_adr.urls", namespace="django_adr")),
]
Run migrations:
python manage.py migrate
Usage
Admin
Visit /admin/django_adr/adr/ to manage ADRs through the Django admin.
HTML views
/adrs/— list all ADRs/adrs/?status=accepted— filter by status/adrs/<number>/— view a single ADR
REST API
GET /adrs/api/adrs/— list all ADRsGET /adrs/api/adrs/<number>/— retrieve a single ADR
Management commands
Create a new ADR:
python manage.py create_adr "Use PostgreSQL" \
--context="We need a relational database." \
--decision="Use PostgreSQL." \
--consequences="Team must know SQL."
Create a new ADR and supersede an existing one in a single step:
python manage.py create_adr "Use CockroachDB" --supersedes=3
This creates the new ADR and automatically marks ADR-0003 as Superseded.
Export all ADRs as Markdown files:
python manage.py export_adrs --output-dir=docs/adr
Each ADR is written to <output-dir>/<number>-<slug>.md.
ADR statuses
| Status | Description |
|---|---|
proposed |
Under discussion |
accepted |
Agreed and in effect |
deprecated |
No longer relevant |
superseded |
Replaced by a newer ADR |
rejected |
Considered and not adopted |
Protecting the views
The HTML views and REST API are public by default. The package does not enforce any authentication strategy — that is left to the host project.
HTML views — in urls.py, wrap the URL include with login_required:
from django.contrib.auth.decorators import login_required
from django.urls import include, path
urlpatterns = [
path("adrs/", login_required(include("django_adr.urls", namespace="django_adr"))),
]
REST API — set DEFAULT_PERMISSION_CLASSES in settings.py:
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],
}
Or scope it to the ADR router only by subclassing ADRViewSet:
from django_adr.api import ADRViewSet
from rest_framework.permissions import IsAuthenticated
class ProtectedADRViewSet(ADRViewSet):
permission_classes = [IsAuthenticated]
Translations
All user-facing strings are translatable. The package ships with an English locale. To generate translations for your project:
python manage.py makemessages -l it
Ensure USE_I18N = True in your project settings.
License
MIT
Metadata
Release files for django-adr 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_adr-1.0.0.tar.gz | 34.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_adr-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.3 kB
Release files / django_adr-1.0.0.tar.gz
| Download URL | django_adr-1.0.0.tar.gz |
|---|---|
| Size | 34.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5fb54d849f7439d7a56402820443ce58ef6ec7419a3af11e22715bd55dc20931
|
|
BLAKE2b-256 checksum How to use checksums |
ddb69e17bf06018269256050113edc2ef0ac236d8520c7578c6fd5d85f2475e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / django_adr-1.0.0-py3-none-any.whl
| Download URL | django_adr-1.0.0-py3-none-any.whl |
|---|---|
| Size | 15.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bb513fbb9b364447f7f364997aaec4fa98c48ead2e897574eac269965f1307e4
|
|
BLAKE2b-256 checksum How to use checksums |
28b8627452ea9e6b33521a42d9968583b3b36cc65652123f11d6ce86c65c7575
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|