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.2.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.2-py3-none-any.whl (38.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_scotty-0.5.2.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.2.tar.gz
Algorithm Hash digest
SHA256 8ab6df002e96a9593edf7c76364865dbb5782abf6955eb88e2472e4622963dc5
MD5 08f4760a5ff15c010c62ffecad8b27d6
BLAKE2b-256 606d9ba4b1c87da06f360fdf6e0596ab4bc5384581bafb02319d0238164b2281

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_scotty-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 41859a56d603c588923c98f9423271a035e27989327647016601952fdab8f2b5
MD5 25b2169561d6b3141626ed97e97dd270
BLAKE2b-256 9295bcc309b467bc921b650ff7ca03c0e613e21c91e6ab7f2f9de6868010b325

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