Metadata-Version: 2.4
Name: django-admin-table-widget
Version: 0.1.0
Summary: A searchable, filterable data-table checkbox widget for Django Admin to make ManyToManyField selection efficient, allowing searches by multiple properties, not just by name.
Author: Mohit Girdhar
License: MIT
Project-URL: Homepage, https://github.com/mohitgirdhar/django-admin-table-widget
Keywords: django,admin,widget,table,filter,search,multiplechoice
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
Classifier: Framework :: Django :: 4.1
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Description-Content-Type: text/markdown
Requires-Dist: Django>=3.2

# django-admin-table-widget

A searchable, filterable data-table checkbox widget for Django Admin to make M2M (ManyToManyField) field selection efficiently, so it can be searchable not by name only, but by multiple columns simultaneously.

## The Problem
Django's default admin interface provides a `<select multiple>` box for `ManyToMany` fields. While you can use `filter_horizontal` to get a dual-list box, there is no built-in way to display related items as a **rich data table** with custom columns, colored badges, inline textual search, and column-specific dropdown filters. 

If you have a form with a complex M2M relationship where the admin user needs to pick items based on multiple properties (e.g. status, type, platform), the standard widgets fall short.

## The Solution
`django-admin-table-widget` provides a drop-in `TableListingWidget` that replaces the default M2M widget with a robust, client-side searchable and filterable table.

![Widget Screenshot](screenshot.png)
*(Replace `screenshot.png` with an actual screenshot of the widget in action!)*

## Installation

```bash
pip install django-admin-table-widget
```

Ensure it's in your `INSTALLED_APPS` so Django can find the widget templates (optional but recommended):
```python
INSTALLED_APPS = [
    # ...
    'django_admin_table_widget',
]
```

## Usage

Define your columns using `ListingColumn` and pass them to the `TableListingWidget`:

```python
from django import forms
from django.contrib import admin
from django_admin_table_widget.widgets import ListingColumn, TableListingWidget
from .models import MyModel, RelatedItem

MY_COLUMNS = [
    ListingColumn("id", "ID", searchable=True),
    ListingColumn("name", "Name", searchable=True),
    ListingColumn("type", "Type", value=lambda obj: obj.get_type_display(), filterable=True),
    ListingColumn("is_active", "Status", badge=True, filterable=True),
]

class MyModelForm(forms.ModelForm):
    items = forms.ModelMultipleChoiceField(
        queryset=RelatedItem.objects.all(),
        widget=TableListingWidget(columns=MY_COLUMNS),
        required=False,
    )

    class Meta:
        model = MyModel
        fields = '__all__'

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    form = MyModelForm
```

### Read-Only Display
You can also use this widget to render a read-only table in your admin display methods (no checkboxes):

```python
from django_admin_table_widget.widgets import render_listing_table

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    readonly_fields = ('items_table',)

    def items_table(self, obj):
        return render_listing_table(MY_COLUMNS, obj.items.all(), name="items")
    items_table.short_description = "Items"
```

## Compatibility
- Highly compatible with third-party admin themes like Django Jet and Jazzmin. It binds to all available jQuery instances and native DOM events to ensure filters always work.
- Inlines its CSS/JS for zero-configuration static file deployment (no need to run `collectstatic` for the widget to work).
