Skip to main content

Advanced tables for django cruds

Project description

Django Scotty

CI Python Versions License Ruff

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:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing)
  3. Add tests for your changes
  4. Ensure all checks pass (uv run pytest, uv run mypy, uv run ruff check)
  5. Submit a Pull Request

License

MIT — see LICENSE.


Credits

Built with:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_scotty-0.5.3.tar.gz (25.7 kB view details)

Uploaded Source

Built Distribution

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

django_scotty-0.5.3-py3-none-any.whl (38.8 kB view details)

Uploaded Python 3

File details

Details for the file django_scotty-0.5.3.tar.gz.

File metadata

  • Download URL: django_scotty-0.5.3.tar.gz
  • Upload date:
  • Size: 25.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.5

File hashes

Hashes for django_scotty-0.5.3.tar.gz
Algorithm Hash digest
SHA256 3f42dcd673ca6956197b40a8a4add22be7fff2b7d8ec6b88b953b6959eb83cf0
MD5 cc9fa8b93227df11fb8675a8301fa362
BLAKE2b-256 919b73a0b48ff79c0d770df2f8551c2ef51340d7de0f3e1e3fa9f1288361d41e

See more details on using hashes here.

File details

Details for the file django_scotty-0.5.3-py3-none-any.whl.

File metadata

File hashes

Hashes for django_scotty-0.5.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b6d0788c0a07f5a3f41793a6f077f1dce72758cec446e5ef17690771ff6e0818
MD5 79b84df53e88c00bb7cecf8152ce31ac
BLAKE2b-256 c8e446853aeffdbec89f69238e8c7d4a596bdcbaf293116685fdb39f061fa15a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page