Skip to main content
Pre-release

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.

Tests PyPI Downloads Python Django License

📚 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 a full admin with filters, badges and change logging (Unfold-themed with the [theme] extra, stock Django admin without it), /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. The Unfold theme is optional (pip install django-snapadmin[theme]) — with it you get the themed UI; without it SnapAdmin renders on Django's built-in admin. If you use Unfold, its apps must precede django.contrib.admin:

INSTALLED_APPS = [
    # Optional themed UI — pip install django-snapadmin[theme]. If used, list before admin:
    "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 djangorestframework, drf-spectacular, django-filter and graphene-django automatically — you only list them. django-unfold is not installed by the base package; add the [theme] extra for the Unfold-themed admin.

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
theme django-unfold Unfold-themed admin UI (falls back to Django's built-in admin without it)
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.

Integrate into an existing project

Adding SnapAdmin to a project you already have? Run the read-only doctor — it inspects your project and prints exactly what to paste (the INSTALLED_APPS ordering, the URL include, the settings block, the install line), editing nothing:

pip install django-snapadmin
snapadmin-init                    # a per-item present/missing checklist with ready-to-paste snippets
snapadmin-init --api --graphql    # also check the REST / GraphQL configuration

Because it only reports and prints snippets, there's no risk of a bad automatic edit — you review each and paste it yourself. → Integration guide


✨ Features

Admin

  • Declarative list_display / search_fields / list_filter straight from field kwargs
  • Unfold-themed responsive UI (optional [theme] extra — falls back to Django's built-in admin), 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

Elasticsearch

  • Per-model DB_ONLY / DUAL / ES_ONLY storage modes with auto-derived index mappings
  • Smart routing?search= on DUAL models runs fuzzy on ES; plain listings stay on SQL
  • es_filter() structured term filters, es_aggregate() facets, es_count() true match totals past the search limit, es_scan() deep scan past the 10k window (source=False streams just the pks of N-million matches, limit=N bounds the walk) — each with a DB fallback when ES is off, or db_fallback=False to fail loudly instead on a table the DB can't scan
  • Resumable bulk reindexsnapadmin_reindex pages by a pk__gt cursor with live progress, --resume, --parallel, and --tune; it fetches only the ES-mapped columns, and --limit N bounds a probe run

Operations

  • GDPR retention (data_retention_days) and an immutable audit trail
  • Error monitoring — spike alerts + daily grouped email digests
  • Health alerts — email when a subsystem probe (DB / Elasticsearch / REST API / GraphQL, each skipped when its feature is off) goes down; snapadmin_health_alert (cron) or the snapadmin.send_health_alert task (Beat), with a cooldown so an outage emails once
  • 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 ETLupsert_from_source() and stale_sync() with a max_fraction wipe guard, a non-raising on_exceed="skip" mode, and a DB-side strategy="last_seen" prune that holds no in-memory key set
  • Pluggable export sources — register a custom row source with SNAPADMIN_EXPORT_SOURCES (ES-query-backed, key-list, or a custom document shape) while the runner keeps its resumable chunking, progress, cancel and storage
  • Structured logging via structlog; i18n in 10 locales
  • One-command diagnosticssnapadmin_info reports the version, connected services (DB / Elasticsearch / Celery), registered models and health as text or --json, with a --health-check readiness probe
  • Feature-adoption auditsnapadmin_info --section features prints a ✓/✗ checklist of which commerce-important capabilities (backups, retention-based deletion, PII masking, audit, read-only models, rate limiting, SSO, …) are actually on or in use in your project vs. left unused
  • Licence auditsnapadmin_license_check reports the licence and 🟢/🟡/🔴 commercial-usability tier of every installed dependency, so you know your install is proprietary-safe

Management commands: snapadmin_info (diagnostics & health), snapadmin_license_check (licence audit), snapadmin_health_alert (email on unhealthy subsystem), 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 SnapField with your own admin introspection
  • Extend a SnapModel — override save(), 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

Fastest — one command, no clone:

pip install django-snapadmin
snapadmin-demo            # downloads the demo, migrates, seeds, and serves at localhost:8000

snapadmin-demo (also python -m snapadmin.quickstart) fetches the demo/ directory from the matching release tag — cached under ~/.cache/snapadmin-demo/, so re-runs are instant and offline — then installs, migrates, seeds and serves it. Add --interactive for a wizard (SQLite/PostgreSQL, admin password, debug), --no-serve to only prepare it, or --skip-install to reuse the current environment. See the demo command guide.

Or from a clone — the full Docker stack (PostgreSQL, Redis and Elasticsearch). The demo lives under demo/ with example models (Product, Customer, Order) and a seeded database; 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 · Integrate an existing project · SnapModel · Field types · Admin registration
APIs REST · GraphQL · Tokens · Integrating auth / JWT / ETL
Search Elasticsearch modes · Query routing · Filters · Facets · Deep scan
Operations Diagnostics (snapadmin_info) · Licence audit · 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 — or run python manage.py snapadmin_license_check for the same inventory computed from what you actually installed, with a commercial-usability verdict.

🤝 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

django_snapadmin-0.1.0b5.tar.gz (492.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_snapadmin-0.1.0b5-py3-none-any.whl (538.1 kB view details)

Uploaded Python 3

File details

Details for the file django_snapadmin-0.1.0b5.tar.gz.

File metadata

  • Download URL: django_snapadmin-0.1.0b5.tar.gz
  • Upload date:
  • Size: 492.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for django_snapadmin-0.1.0b5.tar.gz
Algorithm Hash digest
SHA256 b0dbd73f932a964d1cc385b431169fa2edd241336dc91092e1ecf3caf4616b91
MD5 247371ae66e0c0f4d87576e7456d5f0c
BLAKE2b-256 2283ffe5d3c3430db69c9eade47df8df717f679cbe3a0fbc7a98bf1a68c9cb7b

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_snapadmin-0.1.0b5.tar.gz:

Publisher: publish.yml on drofji/django-snapadmin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_snapadmin-0.1.0b5-py3-none-any.whl.

File metadata

File hashes

Hashes for django_snapadmin-0.1.0b5-py3-none-any.whl
Algorithm Hash digest
SHA256 4146ed2550ef98a50c3c3d4d99ea3443be5433d10e0d66aec7adc0effc9c9f9c
MD5 b96dbfcda067143ac7265ac15dd5b87b
BLAKE2b-256 b7e92a3181e642f1eb94511c285c272b6ca6249dec24820b649c8686b20f2f60

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_snapadmin-0.1.0b5-py3-none-any.whl:

Publisher: publish.yml on drofji/django-snapadmin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.
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