Skip to content

Commit

Permalink
Added compatibility with django-admin-action-forms and any order of d…
Browse files Browse the repository at this point in the history
…ecorators
  • Loading branch information
michalpokusa committed Oct 1, 2024
1 parent 4db88c8 commit f5fd228
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
1 change: 1 addition & 0 deletions django_no_queryset_admin_actions/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .admin import NoQuerySetAdminActionsMixin
from .decorators import no_queryset_action
55 changes: 46 additions & 9 deletions django_no_queryset_admin_actions/decorators.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,60 @@
from functools import wraps
from types import FunctionType
from typing import overload

from django.contrib.admin import ModelAdmin
from django.db.models import QuerySet
from django.http import HttpRequest


NO_QUERYSET_ACTION_ATTRIBUTE = "no_queryset_action"


def no_queryset_action(action_function: FunctionType):
@overload
def no_queryset_action(function: "FunctionType") -> "FunctionType": ...


@overload
def no_queryset_action(
*, permissions: "list[str] | None" = None, description: "str | None" = None
) -> "FunctionType": ...


def no_queryset_action(
function: "FunctionType | None" = None,
*,
permissions: "list[str] | None" = None,
description: "str | None" = None,
):
"""
Decorator to remove `queryset` parameter from being passed to action function.
"""

if getattr(action_function, NO_QUERYSET_ACTION_ATTRIBUTE, None) is not None:
return action_function
def decorator(action_function):
if getattr(action_function, NO_QUERYSET_ACTION_ATTRIBUTE, None) is not None:
return action_function

@wraps(action_function)
def wrapper(*args):

# Compatibility with django-admin-action-forms
modeladmin: ModelAdmin = args[0]
request: HttpRequest = args[1]
rest = [arg for arg in args[2:] if not isinstance(arg, QuerySet)]

return action_function(modeladmin, request, *rest)

setattr(wrapper, NO_QUERYSET_ACTION_ATTRIBUTE, True)

if permissions is not None:
setattr(wrapper, "allowed_permissions", permissions)

@wraps(action_function)
def wrapper(*args, **kwargs):
modeladmin, request, queryset, *rest = args
return action_function(modeladmin, request, *rest, **kwargs)
if description is not None:
setattr(wrapper, "short_description", description)

setattr(wrapper, NO_QUERYSET_ACTION_ATTRIBUTE, True)
return wrapper

return wrapper
if function is None:
return decorator
else:
return decorator(function)

0 comments on commit f5fd228

Please sign in to comment.