Metadata-Version: 2.4
Name: django-no-queryset-admin-actions
Version: 1.2.1
Summary: Extension for the Django admin panel that makes it possible to add actions that do not require a queryset to run.
Author: Michał Pokusa
Maintainer: Michał Pokusa
Project-URL: Repository, https://github.com/michalpokusa/django-no-queryset-admin-actions
Project-URL: Changelog, https://github.com/michalpokusa/django-no-queryset-admin-actions/blob/main/CHANGELOG.md
Keywords: django,admin,action,actions,queryset,no queryset,optional,empty,selection,items,no items
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
Classifier: Framework :: Django :: 4.1
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 4
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
Classifier: Framework :: Django :: 5
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: django>=3.2
Dynamic: license-file


# django-no-queryset-admin-actions

<p float="left">
    <a href="https://pypi.org/project/django-no-queryset-admin-actions/">
        <img src="https://img.shields.io/pypi/v/django-no-queryset-admin-actions?color=0073b7"/>
    </a>
    <a href="https://www.djangoproject.com/">
        <img src="https://img.shields.io/badge/3.2.x, 4.x.x, 5.x.x-a?style=flat&logo=django&label=django&labelColor=0c4b33&color=616161">
    </a>
</p>

Extension for the Django admin panel that makes it possible to add actions that do not require a queryset to run.

Works with [django-admin-action-forms](https://pypi.org/project/django-admin-action-forms/).

- [🔌 Installation](#-installation)
- [✏️ Examples](#️-examples)
  - [No queryset actions](#no-queryset-actions)
  - [Optional queryset actions](#optional-queryset-actions)

## 🔌 Installation

1. Install using ``pip``:

    ```bash
    $ pip3 install django-no-queryset-admin-actions
    ```

2. Add `'django_no_queryset_admin_actions'` to your `INSTALLED_APPS` setting.
    ```python
    INSTALLED_APPS = [
        ...
        'django_no_queryset_admin_actions',
    ]
    ```

## ✏️ Examples

### No queryset actions

Let's say you have an action that fetches external orders from an API. You don't need a queryset to run this action,
but Django requires it by default. By using the `@no_queryset_action`, you can bypass that, and create actions that can
be run without selecting any objects.

<img src="https://raw.githubusercontent.com/michalpokusa/django-no-queryset-admin-actions/main/docs/example.gif" width="100%"></img>

```python
from django.contrib.admin import ModelAdmin, register

from django_no_queryset_admin_actions import NoQuerySetAdminActionsMixin, no_queryset_action


@register(ExternalOrder)
class ExternalOrderAdmin(NoQuerySetAdminActionsMixin, ModelAdmin):

    @no_queryset_action(description="Fetch external orders")
    def fetch_external_orders(self, request): # <- No `queryset` parameter
        ...

    actions = [fetch_external_orders]
```

### Optional queryset actions

Another use case is when you have an action that can be run on a specific queryset, but you also want to allow running it without selecting any objects.

This type of action could be used to e.g.:
- default to all, or a filtered subset of objects when no selection is made
- choose a random object if no specific item is selected

Leveraging the `@optional_queryset_action` decorator, you can create actions that run whether or not objects are selected.

Let's say, that `ExternalOrder` objects fetched in the previous example may sometimes need updating. In this example, if no objects are selected, `queryset` will be empty, and the action will default to updating all `ExternalOrder` objects.

```python
from django.contrib.admin import ModelAdmin, register

from django_no_queryset_admin_actions import NoQuerySetAdminActionsMixin, optional_queryset_action


@register(ExternalOrder)
class ExternalOrderAdmin(NoQuerySetAdminActionsMixin, ModelAdmin):

    @optional_queryset_action(description="Update external orders")
    def update_external_orders(self, request, queryset): # <- `queryset` can be empty

        if not queryset:
            queryset = ExternalOrder.objects.all()

        ...

    actions = [update_external_orders]
```
