Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,43 @@ class MovieAdmin(GroupedActionAdminMixin, admin.ModelAdmin):
# …
```

The order of the groups is determined by the order of the individual actions: the first action for that group for each group determines how the groups are listed.
The order of the groups is determined by the order of the individual actions: the first action for that group for each group determines how the groups are listed.

## Simpler `SimpleListFilter`s

Django allows to add extra filters on the Django admin, but even with a `SimpleListFilter`, they are cumbersome to make. We define a `ChoiceListFilter` which can be
used to make these based on a dictionary, and add a function `adminfilter_factory(..)` to define such classes in a more convenient way.

Once can define such simple list filter by working with a dict like:

```python3
from django.db.models import Q
from django.db.models.functions import Now
from django_adminlink.admin import ChoiceListFilter

class ArchiveStatusFilter(ChoiceListFilter):
title = 'Archive status'
parameter_name = 'archive_status'
choices = {
'active': ('Active', ~Q(archived_at__lte=Now())),
'archived': ('Archived', Q(archived_at__lte=Now()))
}
```

so a dictionary that maps the key of the filter on a 2-tuple with the verbose name as first item, and the Django filter (a `Q` object) as second one. Because it is a dictionary, it is also impossible to specify the same key twice.

We can also define this with the `adminfilter_factory(..)` as follows:


```python3
from django.db.models import Q
from django_adminlink.admin import adminfilter_factory

ARCHIVE_OPTIONS = [
('active', 'Active', ~Q(archived_at__lte=Now())),
('archived', 'Archived', Q(archived_at__lte=Now()))
]
ArchiveStatusFilter = adminfilter_factory('archive_status', ARCHIVE_OPTIONS)
```

here we can use the same dictionary structure, or any iterable of items with at least three items.
28 changes: 28 additions & 0 deletions django_adminlink/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,31 @@ def get_action_choices(self, request, default_choices=models.BLANK_CHOICE_DASH):

class GroupedActionAdmin(SingleItemActionMixin, admin.ModelAdmin):
pass


class ChoiceListFilter(admin.SimpleListFilter):
choices = {}

def lookups(self, request, model_admin):
return [(k, v) for k, (v, *__) in self.choices.items()]

def queryset(self, request, queryset):
val = self.choices.get(self.value())
if val and len(val) >= 2:
__, cond, *__ = val
return queryset.filter(cond)
return queryset


def adminfilter_factory(parameter_name, choices, verbose_name=None):
default_verbose_name = parameter_name.replace("_", " ")
if verbose_name is None:
verbose_name = default_verbose_name.capitalize()
class_name = default_verbose_name.title().replace(" ", "")
if not isinstance(choices, dict):
choices = {k: vs for k, *vs in choices}
return type(
f"{class_name}Filter",
(ChoiceListFilter,),
{"title": verbose_name, "parameter_name": parameter_name, "choices": choices},
)
Empty file added django_adminlink/tests.py
Empty file.
Loading