This release is a pre-release and may not be stable for production use.
🚀 SnapAdmin — Declarative Django Admin & API
Define your model fields once — get a feature-rich Django admin, a REST API with Swagger docs, a
GraphQL API, and optional Elasticsearch search. Every surface can be switched on or off with a
single setting, and expensive ?search= queries are routed to Elasticsearch automatically when a
model is mirrored there — plain listings stay on the database.
📚 Full Documentation — configuration guide, API reference, examples 📦 Django Packages — compare SnapAdmin against other Django admin packages 📝 Changelog · 🔒 Security policy
⚡ The Core Idea — 3 Steps, Full Stack
# 1. Define a model
from snapadmin import fields as snap, models as snap_models
class Product(snap_models.SnapModel):
name = snap.SnapCharField(max_length=200, searchable=True, show_in_list=True)
price = snap.SnapDecimalField(max_digits=10, decimal_places=2, filterable=True)
available = snap.SnapBooleanField(default=True, filterable=True)
# Optional: mirror to Elasticsearch, auto-delete after a year
# es_storage_mode = snap_models.EsStorageMode.DUAL
# data_retention_days = 365
# 2. settings.py — every surface is a toggle
SNAPADMIN_REST_API_ENABLED = True
SNAPADMIN_GRAPHQL_ENABLED = True
SNAPADMIN_SWAGGER_ENABLED = True
# 3. admin.py
from snapadmin.models import SnapModel
SnapModel.register_all_admins()
That's it — you get an Unfold-themed admin with filters, badges and change logging, /api/product/
CRUD with Swagger docs, an allDemoProducts GraphQL field, and typo-tolerant search when
Elasticsearch is on.
→ Field types · SnapModel reference · Admin registration
👀 What You'll See
These screens come from the bundled demo, not the package — they illustrate what SnapAdmin generates for your models.
┌────────────────────────────────────────────────────────────┐
│ SnapAdmin 🔍 Search... admin ▾│
├──────────────┬─────────────────────────────────────────────┤
│ DEMO APP │ Products + Add │
│ Categories │ ┌──────────────────────────────────────────┐│
│ Tags │ │ Name Price In Stock Category ││
│ Products │ │ Premium Laptop $249 ● Active Audio ││
│ Customers │ │ Ergonomic Mouse $89 ● Active Access. ││
│ Orders │ │ USB-C Hub $49 ○ Out Electr. ││
│ Audit Logs │ └──────────────────────────────────────────┘│
│ SYSTEM │ Sidebar filters: Price range │ Available │
│ Dashboard │ Category │ │
└──────────────┴─────────────────────────────────────────────┘
Also generated: Swagger UI at /api/docs/, a GraphQL playground at /api/graphql/, and a
system dashboard at /admin/snapadmin/dashboard/ showing per-model row counts, storage modes and
scheduled jobs.
📦 Installation
pip install django-snapadmin
Requires Python ≥ 3.10 and Django ≥ 5.2. The package is beta — the public API is
stabilising but may still change before 0.1.0 stable, so pin an exact version in production.
Add the stack to INSTALLED_APPS — order matters, unfold must precede django.contrib.admin:
INSTALLED_APPS = [
"unfold", "unfold.contrib.filters", "unfold.contrib.forms", "unfold.contrib.inlines",
"django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes",
"django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles",
"rest_framework", "drf_spectacular", "django_filters", "graphene_django", "snapadmin",
# your apps …
]
Installing SnapAdmin pulls in django-unfold, djangorestframework, drf-spectacular,
django-filter and graphene-django automatically — you only list them.
Optional extras
The base install is self-contained and carries only permissive licences (MIT/BSD/Apache), so it is safe for commercial and proprietary use. Opt into the rest:
| Extra | Pulls in | For |
|---|---|---|
elasticsearch |
elasticsearch |
Full-text search, DUAL / ES_ONLY models |
celery |
celery, django-celery-beat, django-celery-results |
Background tasks (export, GDPR purge, digests, backups) |
backup |
paramiko |
SFTP offsite database backups |
extra-settings |
django-extra-settings |
In-admin dynamic key/value Setting model |
wysiwyg |
django-ckeditor-5 |
Rich-text fields — bundles CKEditor 5 (GPL-or-commercial) |
autocomplete-filter |
django-admin-autocomplete-filter |
AutocompleteFilter list filters (LGPL) |
all |
everything above | — |
→ Full installation guide —
compatibility matrix, extras gotchas, and the licensing notes for [wysiwyg] and MySQL drivers.
✨ Features
Admin
- Declarative
list_display/search_fields/list_filterstraight from field kwargs - Unfold-themed responsive UI, colour-coded status badges, horizontal rows and tabs
- Date and numeric range filters; field-level change logging (
old → new) with a history view - Offline mode — per-model IndexedDB prefetch, real backend health checks, sync on reconnect
APIs
- REST CRUD for every
SnapModel, with Swagger + ReDoc, filters derived from field types, and streaming/async export - GraphQL schema generated from the same models, auth-enforced on every traversed relation
- API tokens hashed at rest (SHA-256), shown once, scoped per model — or plug in JWT/session/custom auth
- Privacy controls:
api_exclude_fields,api_write_fields(mass-assignment guard),api_json_filters, PII masking
Elasticsearch
- Per-model
DB_ONLY/DUAL/ES_ONLYstorage modes with auto-derived index mappings - Smart routing —
?search=onDUALmodels runs fuzzy on ES; plain listings stay on SQL es_filter()structured term filters,es_aggregate()facets,es_scan()deep scan past the 10k window — each with a DB fallback when ES is off
Operations
- GDPR retention (
data_retention_days) and an immutable audit trail - Error monitoring — spike alerts + daily grouped email digests
- 3-2-1 database backups — local, network share, and offsite FTPS/SFTP
- Large-dataset tuning — auto
list_select_related(no admin N+1), estimated counts, per-model paging - Generic ETL —
upsert_from_source()andstale_sync()with amax_fractionwipe guard - Structured logging via
structlog; i18n in 10 locales
Management commands: snapadmin_reindex, db_backup, send_error_digest, purge_expired_data.
⏱ Nothing runs on its own. SnapAdmin ships no daemon — the retention purge, digests and backups need a Celery Beat entry or a cron line. See Background tasks & scheduling.
⚙️ Configuration
Every surface is a plain Django setting; disabling one removes its URL routes entirely (404):
SNAPADMIN_REST_API_ENABLED = True # REST CRUD endpoints
SNAPADMIN_GRAPHQL_ENABLED = True # GraphQL endpoint
SNAPADMIN_SWAGGER_ENABLED = True # Swagger UI + ReDoc
SNAPADMIN_ES_QUERY_ROUTING = True # route ?search= on DUAL models to Elasticsearch
SNAPADMIN_GRAPHQL_REQUIRE_AUTH = True # auth + per-model perms on every resolver
SNAPADMIN_URL_PREFIX = "" # relocate the whole API surface
→ Full settings reference — every
SNAPADMIN_* knob with its default, grouped by area.
🧩 Extending
SnapAdmin is meant to be customised, not forked:
- Add field types — subclass
SnapFieldwith your own admin introspection - Extend a
SnapModel— overridesave(), add managers, mix in your own behaviour - Add or override REST endpoints — mount your router before SnapAdmin's
- Swap auth, permissions and the ES client — configuration, no code
- Override admin templates and the dashboard — standard Django template resolution
→ Extending & Overriding guide
🌟 Trying the Demo
The repository ships a runnable demo under demo/ — example models (Product, Customer,
Order), a seeded database, and a Docker stack with PostgreSQL, Redis and Elasticsearch. It is not
published to PyPI; only the top-level snapadmin/ package is.
git clone https://github.com/drofji/django-snapadmin.git
cd django-snapadmin
cp demo/dist.env demo/.env
docker compose -f demo/docker-compose.yml up --build
Then open http://localhost:8000/admin/ (admin / admin).
→ Demo guide — Traefik overlays with HTTPS, the Elasticsearch profile, manual setup without Docker, and the seed command.
📖 Documentation
| Topic | |
|---|---|
| Getting started | Installation · SnapModel · Field types · Admin registration |
| APIs | REST · GraphQL · Tokens · Integrating auth / JWT / ETL |
| Search | Elasticsearch modes · Query routing · Filters · Facets · Deep scan |
| Operations | Celery & scheduling · GDPR · Backups · Error monitoring · Performance |
| Reference | All settings · Enterprise config · Extending · Migration guides |
Upgrading from drofji-automatically-django-admin? See the
migration guide.
🔒 Security
API tokens are hashed at rest, rich-text HTML is sanitized before display, GraphQL enforces permissions on every traversed relation, and PII masking is available on both APIs. Report vulnerabilities privately — see SECURITY.md for the policy, the supported-versions row, and the production-hardening checklist.
Third-party dependency licences are inventoried in THIRD_PARTY_NOTICES.md.
🤝 Contributing
See CONTRIBUTING.md. The suite must stay green with 100% coverage on snapadmin/:
pytest
📜 License
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_snapadmin-0.1.0b3.tar.gz.
File metadata
- Download URL: django_snapadmin-0.1.0b3.tar.gz
- Upload date:
- Size: 435.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44713945d7b0ad5c8a0c9111ed0ae9c6e174ceb788f65177e05900369729f7fb
|
|
| MD5 |
a90cced9627af9d289b1d61242c62307
|
|
| BLAKE2b-256 |
8919139ac0a09fe51c9d08e7c4b7a96b3f2922f7221d9c5e3c290d6e3d9569d2
|
Provenance
The following attestation bundles were made for django_snapadmin-0.1.0b3.tar.gz:
Publisher:
publish.yml on drofji/django-snapadmin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_snapadmin-0.1.0b3.tar.gz -
Subject digest:
44713945d7b0ad5c8a0c9111ed0ae9c6e174ceb788f65177e05900369729f7fb - Sigstore transparency entry: 2206266641
- Sigstore integration time:
-
Permalink:
drofji/django-snapadmin@3f11766d7612cb5a122b7701ca90f34cd14fb0c8 -
Branch / Tag:
refs/tags/v0.1.0b3 - Owner: https://github.com/drofji
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3f11766d7612cb5a122b7701ca90f34cd14fb0c8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file django_snapadmin-0.1.0b3-py3-none-any.whl.
File metadata
- Download URL: django_snapadmin-0.1.0b3-py3-none-any.whl
- Upload date:
- Size: 475.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
599736ae359d9d7354533bf6704cdcc1768c413fc06e0f2fac4e4a6a1f7b2a6e
|
|
| MD5 |
bafa14e526d4c2495d609749837afb02
|
|
| BLAKE2b-256 |
7adafc65c0b9bbb1b830373c02eb3bdd0ef20f687dadee3e801fa60aa53a9e5f
|
Provenance
The following attestation bundles were made for django_snapadmin-0.1.0b3-py3-none-any.whl:
Publisher:
publish.yml on drofji/django-snapadmin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_snapadmin-0.1.0b3-py3-none-any.whl -
Subject digest:
599736ae359d9d7354533bf6704cdcc1768c413fc06e0f2fac4e4a6a1f7b2a6e - Sigstore transparency entry: 2206266662
- Sigstore integration time:
-
Permalink:
drofji/django-snapadmin@3f11766d7612cb5a122b7701ca90f34cd14fb0c8 -
Branch / Tag:
refs/tags/v0.1.0b3 - Owner: https://github.com/drofji
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3f11766d7612cb5a122b7701ca90f34cd14fb0c8 -
Trigger Event:
push
-
Statement type: