Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
dj-kaos-utils / admin / filters.py
Size: Mime:
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',
)