Django Scotty
Advanced table views for Django with CRUD operations, filtering, export, and htmx-powered modals.
Built on top of django-tables2, django-filter, and django-cotton.
Features
- CRUD Views — Ready-to-use Create, Read, Update, Delete views with a consistent look
- Table Views — Filterable, sortable, paginated table views via django-tables2
- Filtering — Integrated django-filters with Bootstrap 5 UI
- Export to Excel — One-click export to XLSX via tablib
- htmx Modals — Create/Update forms in modals with zero custom JS
- Pagination Fix — Invalid page numbers redirect gracefully instead of 404/500
- Bulk Actions — Define custom actions on table rows
- Modern UI — django-cotton components + Bootstrap 5 + crispy-forms
Requirements
- Python >= 3.12
- Django >= 5.1 (via django-cotton constraint)
- django-cotton >= 2.1
- django-tables2 >= 2.7
- django-filter >= 25.1
- django-crispy-forms >= 2.4 + crispy-bootstrap5
- tablib >= 3.8 (with XLSX support)
Installation
pip install django-scotty
Or with uv:
uv pip install django-scotty
Add the required apps to INSTALLED_APPS:
INSTALLED_APPS = [
...
"django_cotton",
"django_tables2",
"django_filters",
"django_scotty",
...
]
Quick Start
List View (table)
# views.py
import django_tables2 as tables
from django_scotty.views import CottonTableView
from .models import Product
class ProductTable(tables.Table):
class Meta:
model = Product
fields = ["name", "price", "stock", "category"]
class ProductListView(CottonTableView):
model = Product
table_class = ProductTable
title = "Products"
paginate_by = 25
# urls.py
from django.urls import path
from .views import ProductListView
urlpatterns = [
path("products/", ProductListView.as_view(), name="product-list"),
]
Create View
from django_scotty.views import GenericCreateView
from .models import Product
from .forms import ProductForm
class ProductCreateView(GenericCreateView):
model = Product
form_class = ProductForm
title_form = "New Product"
Update View
from django_scotty.views import GenericUpdateView
class ProductUpdateView(GenericUpdateView):
model = Product
form_class = ProductForm
title_form = "Edit Product"
Delete View
from django_scotty.views import GenericDeleteView
class ProductDeleteView(GenericDeleteView):
model = Product
Detail View
from django_scotty.views import GenericDetailView
class ProductDetailView(GenericDetailView):
model = Product
URL auto-discovery
For a cleaner setup, gather all views from a scotty/ directory in your app:
# urls.py
from django_scotty.urls import load_scotty_urls, add_urls
from myapp import scotty
urlpatterns = [
*add_urls([scotty]),
]
# or auto-discover from an app:
urlpatterns = [
*load_scotty_urls("myapp"),
]
Filtering
Add a FilterSet and wire it to your list view:
import django_filters
class ProductFilter(django_filters.FilterSet):
class Meta:
model = Product
fields = {
"name": ["exact", "icontains"],
"category": ["exact"],
"price": ["gte", "lte"],
}
class ProductListView(CottonTableView):
model = Product
table_class = ProductTable
filterset_class = ProductFilter
paginate_by = 25
htmx Modal Forms
GenericCreateView and GenericUpdateView render inside an htmx-powered Bootstrap modal by default when the request includes the HX-Request header.
On success, they return an HX-Refresh response that tells the parent page to reload the table. No JavaScript required beyond the htmx library.
class ProductCreateView(GenericCreateView):
model = Product
form_class = ProductForm
title_form = "New Product"
auto_forms_buttons = True # adds Save / Cancel buttons automatically
Export
Every CottonTableView includes a built-in "Export to XLSX" button. The export uses tablib and respects the current filter/sort state.
Customize the filename:
class ProductListView(CottonTableView):
model = Product
table_class = ProductTable
export_name = "products_report" # default: slugified model name
Configuration
Set SCOTTY_CONFIG in your Django settings:
SCOTTY_CONFIG = {
"BUTTON_VARIANT": "primary", # default button variant
"BUTTON_VARIANT_DANGER": "danger", # delete button variant
"BUTTON_STYLE": "solid", # solid (filled) or outline
}
Available variants: primary, secondary, success, danger, warning, info, light, dark.
Development
Setup
# Clone the repo
git clone https://github.com/jmschillaci/django-scotty.git
cd django-scotty
# Install with dev dependencies
uv sync --group dev
Run tests
# Full suite
uv run pytest -v --cov=src/django_scotty
# With tox (requires tox and the Python versions installed)
tox
tox -e lint # ruff checks only
tox -e type # mypy only
tox -e py312 # tests on Python 3.12 only
Lint & type check
uv run ruff check src/django_scotty tests
uv run ruff format --check src/django_scotty tests
uv run mypy src/django_scotty
Requirements
Full dependency list in pyproject.toml.
| Dependency | Minimum Version |
|---|---|
| Python | 3.12 |
| Django | 5.1+ |
| django-cotton | 2.1 |
| django-tables2 | 2.7 |
| django-filter | 25.1 |
| django-crispy-forms | 2.4 |
| crispy-bootstrap5 | 2024.10 |
| tablib[xlsx] | 3.8 |
| django-htmx | 1.26 |
Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing) - Add tests for your changes
- Ensure all checks pass (
uv run pytest,uv run mypy,uv run ruff check) - Submit a Pull Request
License
MIT — see LICENSE.
Credits
Built with:
Release files for django-scotty 0.5.3
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_scotty-0.5.3.tar.gz | 25.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_scotty-0.5.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 64.5 kB
Release files / django_scotty-0.5.3.tar.gz
| Download URL | django_scotty-0.5.3.tar.gz |
|---|---|
| Size | 25.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3f42dcd673ca6956197b40a8a4add22be7fff2b7d8ec6b88b953b6959eb83cf0
|
|
BLAKE2b-256 checksum How to use checksums |
919b73a0b48ff79c0d770df2f8551c2ef51340d7de0f3e1e3fa9f1288361d41e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.5
|
Release files / django_scotty-0.5.3-py3-none-any.whl
| Download URL | django_scotty-0.5.3-py3-none-any.whl |
|---|---|
| Size | 38.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b6d0788c0a07f5a3f41793a6f077f1dce72758cec446e5ef17690771ff6e0818
|
|
BLAKE2b-256 checksum How to use checksums |
c8e446853aeffdbec89f69238e8c7d4a596bdcbaf293116685fdb39f061fa15a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.5
|