Metadata-Version: 2.4
Name: django-chassis
Version: 1.0.22
Summary: Declarative Django Admin chassis: mixin, site, options, pages, and dashboard
Author-email: Raman Marozau <r.morozov@rdd-lab.com>
License-Expression: MIT
Project-URL: Homepage, https://django-chassis.rdd-lab.com/
Project-URL: Documentation, https://django-chassis.rdd-lab.com/
Project-URL: Issues, https://github.com/RDDLab/Django-Chassis/issues
Project-URL: Repository, https://github.com/RDDLab/Django-Chassis
Project-URL: Changelog, https://github.com/RDDLab/Django-Chassis/blob/main/CHANGELOG.md
Keywords: django,admin,dashboard,chassis
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Framework :: Django
Classifier: Framework :: Django :: 6.0
Classifier: Framework :: Django :: 6.1
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: <3.15,>=3.13
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: django>=6.0
Requires-Dist: pygments>=2.18
Requires-Dist: openpyxl>=3.1
Requires-Dist: geoip2>=4.8
Requires-Dist: netaddr>=1.3.0
Requires-Dist: device-detector>=6.4.0
Provides-Extra: gunicorn
Requires-Dist: gunicorn>=26.1.0; extra == "gunicorn"
Provides-Extra: uvicorn
Requires-Dist: uvicorn[standard]<1,>=0.54.0; extra == "uvicorn"
Provides-Extra: dramatiq
Requires-Dist: dramatiq<3,>=2.2.1; extra == "dramatiq"
Provides-Extra: celery
Requires-Dist: celery>=5.3; extra == "celery"
Provides-Extra: all
Requires-Dist: gunicorn>=26.1.0; extra == "all"
Requires-Dist: uvicorn[standard]<1,>=0.54.0; extra == "all"
Requires-Dist: dramatiq<3,>=2.2.1; extra == "all"
Requires-Dist: celery>=5.3; extra == "all"
Dynamic: license-file

<div align="center">
  <img src="https://github.com/RDDLab/Django-Chassis/raw/main/docs/static/img/logo.svg" alt="Django-Chassis" width="560">

  <p><strong>A declarative, fully typed chassis for building polished Django Admin applications.</strong></p>

  <p>
    <a href="https://django-chassis.rdd-lab.com/">Documentation</a> ·
    <a href="https://django-chassis.rdd-lab.com/getting-started">Quick start</a> ·
    <a href="https://django-chassis.rdd-lab.com/api-reference">API reference</a> ·
    <a href="https://github.com/RDDLab/Django-Chassis/blob/main/CHANGELOG.md">Changelog</a>
  </p>

  <p>
    <a href="https://pypi.org/project/django-chassis/"><img src="https://img.shields.io/badge/release-1.0.22-0f766e?style=flat-square" alt="Django-Chassis 1.0.22"></a>
    <a href="https://pypi.org/project/django-chassis/"><img src="https://img.shields.io/pypi/pyversions/django-chassis.svg?style=flat-square" alt="Supported Python versions"></a>
    <a href="https://pypi.org/project/django-chassis/"><img src="https://img.shields.io/pypi/djversions/django-chassis.svg?style=flat-square" alt="Supported Django versions"></a>
    <a href="https://pypi.org/project/django-chassis/"><img src="https://img.shields.io/pypi/types/django-chassis.svg?style=flat-square" alt="Typed package"></a>
    <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="MIT license"></a>
  </p>

  <p>
    <a href="https://github.com/RDDLab/Django-Chassis/actions/workflows/testing.yml"><img src="https://img.shields.io/github/actions/workflow/status/RDDLab/Django-Chassis/testing.yml?branch=main&amp;label=tests&amp;style=flat-square" alt="Test status"></a>
    <a href="https://results.pre-commit.ci/latest/github/RDDLab/Django-Chassis/main"><img src="https://results.pre-commit.ci/badge/github/RDDLab/Django-Chassis/main.svg" alt="pre-commit.ci status"></a>
  </p>
</div>

---

Django-Chassis gives a project a structured `AdminSite`, composable
`ModelAdmin` options, custom pages, dashboard contracts, and a complete template
overlay. Domain models and business rules stay in the project; Chassis provides
the reusable Admin application layer around them.

## Features

- **Declarative configuration** — compose the Admin with
  `ChassisAdminSiteMixin`, `ChassisAdminMixin`, and immutable `options`.
- **A polished changelist** — search, filters, date hierarchy, tabs, badges,
  pretty JSON, and decimal-amount presentation without ad-hoc template forks.
- **Row, list, and object actions** — permission-aware buttons, confirmation, and condition methods.
- **Related data** — independently paginated tables and typed repeatable inputs
  with native or application-owned form-data processing.
- **Custom pages** — permission-aware pages, personal pages, information pages, and timelines.
- **Dashboard contracts** — metrics, charts, alerts, actions, a four-column grid, and live refresh at `dashboard/live/`.
- **Import/export** — JSON/XML in, JSON/XML/CSV/XLSX out, preview/apply, history, a shared worker protocol with optional Celery/Dramatiq providers.
- **Users and security** — profiles, sessions, login-attempt limits, GeoIP country detection, and an Admin audit journal.
- **Fully typed** — ships `py.typed` and is checked with Pyrefly in strict mode.

## Installation

```bash
pip install django-chassis
```

Version `1.0.22` requires Python 3.13 or 3.14 and Django 6.0+.

Put `'django_chassis'` **before** `'django.contrib.admin'` so package templates overlay the stock Admin:

```python
INSTALLED_APPS = [
    'django_chassis',
    'django.contrib.admin',
    # ...
]
```

Background import/export is optional:

```bash
pip install 'django-chassis[dramatiq]'
# or
pip install 'django-chassis[celery]'
```

For WSGI projects, Chassis provides an optional Gunicorn management command:

```bash
pip install 'django-chassis[gunicorn]'
python manage.py run_gunicorn --port=8000 --workers=2
```

For ASGI projects, use the optional Uvicorn command:

```bash
pip install 'django-chassis[uvicorn,dramatiq]'
python manage.py run_uvicorn --host 127.0.0.1 --port 8000 --workers 1 --reload
```

`run_uvicorn` resolves `ASGI_APPLICATION` or an explicit `--app`; it does not
require a project-specific server command. Extras can be combined.
`django-chassis[all]` installs Gunicorn, Uvicorn, Dramatiq and Celery. The base
package installs none of these optional runtimes. Selecting an extra installs
its dependencies; the application still configures its worker broker and database.
For PostgreSQL jobs, install and configure the chosen PostgreSQL broker and driver
in the application. Installing an extra does not enable import/export or start workers.

## Quick start

Create a Chassis `AdminSite`, register a model, and mount the site in `urls.py`:

```python
from django.contrib.admin import AdminSite, ModelAdmin
from django.urls import path
from django.utils.translation import gettext_lazy as _

from django_chassis.mixins import ChassisAdminMixin, ChassisAdminSiteMixin
from django_chassis.options import RowActionsOption, SearchOption

from catalog.models import Book


class CustomAdminSite(ChassisAdminSiteMixin, AdminSite):
    chassis_brand_name = _('My project')
    chassis_brand_logo_static_path = 'img/logo.png'


admin_site = CustomAdminSite(name='admin')


class BookAdmin(ChassisAdminMixin, ModelAdmin):
    options = [SearchOption(fields=['title', 'isbn']), RowActionsOption()]


admin_site.register(Book, BookAdmin)

urlpatterns = [path('admin/', admin_site.urls)]
```

> `ChassisAdminSiteMixin` and `ChassisAdminMixin` must come before their Django
> classes in the MRO.

## Documentation

Read the full guides, architecture notes, option reference, and dashboard
contracts at **[django-chassis.rdd-lab.com](https://django-chassis.rdd-lab.com/)**.

## Testing

```bash
uv sync --group dev
uv run pytest
```

## License

Distributed under the [MIT License](https://opensource.org/licenses/MIT).

## Support the project

<a href="https://nowpayments.io/donation?api_key=7664bfa5-ea12-4ded-9c3b-8a498d437114" target="_blank" rel="noreferrer noopener">
    <img src="https://nowpayments.io/images/embeds/donation-button-white.svg" alt="Cryptocurrency & Bitcoin donation button by NOWPayments">
</a>
