Repository URL to install this package:
Version:
0.2.0a4 ▾
|
from typing import Sequence
from django.contrib import admin
class BooleanAdminFilter(admin.SimpleListFilter):
"""
An admin filter that works like an on-off switch; two options: on, off (all)
Example:
>>> class ByAvailableFilter(BooleanAdminFilter):
>>> title = "availability"
>>> parameter_name = 'is_available'
>>>
>>> def filter(self, request, queryset):
>>> return queryset.filter(is_available=True)
"""
def lookups(self, request, model_admin):
return (
('on', "On"),
)
def queryset(self, request, queryset):
if self.value() == 'on':
return self.filter(request, queryset)
return queryset
def filter(self, request, queryset):
"""
Override this method to filter the queryset when the filter value is set to True
:param request: the request from the admin site
:param queryset: the queryset passed by the admin
:return: filtered queryset
"""
raise NotImplementedError
class QuerysetChoiceFilter(admin.SimpleListFilter):
"""
Admin filter that lets the developer create filters that call the corresponding model's queryset methods. Define the
queryset methods you want to use in `queryset_filters`.
:param queryset_filters: A sequence of the names of the queryset filters you want to use. Optionally pass each item
as a tuple of (queryset_method, verbose_name).
Example:
>>> class BlogPostsQuerysetChoiceFilter(QuerysetChoiceFilter):
>>> title = "blog post states"
>>> parameter_name = 'qs'
>>>
>>> queryset_filters = ('draft', 'published')
"""
queryset_filters: Sequence[str | tuple[str, str]] = ()
def lookups(self, request, model_admin):
lookups = []
for filter_def in self.queryset_filters:
if isinstance(filter_def, tuple):
key, verbose_name = filter_def
else:
key, verbose_name = filter_def, filter_def.replace('_', ' ').capitalize()
lookups.append((key, verbose_name))
return lookups
def queryset(self, request, queryset):
value = self.value()
if value in self.queryset_filters:
return getattr(queryset, value)()
return queryset
class YesNoAdminFilter(admin.SimpleListFilter):
"""
Admin filter with three options: yes, no and all.
Example:
>>> class IsArchivedFilter(BooleanAdminFilter):
>>> title = "archived"
>>> parameter_name = 'is_archived'
>>>
>>> def filter_yes(self, request, queryset):
>>> return queryset.filter(is_archived=True)
>>>
>>> def filter_no(self, request, queryset):
>>> return queryset.filter(is_archived=False)
"""
def lookups(self, request, model_admin):
return (
('yes', "Yes"),
('no', "No"),
)
def queryset(self, request, queryset):
if self.value() == 'yes':
return self.filter_yes(request, queryset)
if self.value() == 'no':
return self.filter_no(request, queryset)
return queryset
def filter_yes(self, request, queryset):
"""
Override this method to filter the queryset when the filter value is set to yes
:param request: the request from the admin site
:param queryset: the queryset passed by the admin
:return: filtered queryset
"""
raise NotImplementedError
def filter_no(self, request, queryset):
"""
Override this method to filter the queryset when the filter value is set to no
:param request: the request from the admin site
:param queryset: the queryset passed by the admin
:return: filtered queryset
"""
raise NotImplementedError
class EnhancedSimpleListFilter(admin.SimpleListFilter):
default_option_display = "All"
def choices(self, changelist):
g = super().choices(changelist)
yield {
'selected': self.value() is None,
'query_string': changelist.get_query_string(remove=[self.parameter_name]),
'display': self.default_option_display,
}
next(g)
yield from g
__all__ = (
'BooleanAdminFilter',
'QuerysetChoiceFilter',
'YesNoAdminFilter',
'EnhancedSimpleListFilter',
)