Skip to content

GenericDeleteBulkView

Generated view class for DeleteBulkAction.

GenericDeleteBulkView

djadmin.factories.base.GenericDeleteBulkView

DeleteBulkAction View class for site.None generated by ViewFactory.

Base class: djadmin.views.BulkDeleteView
Mixins: PermissionMixin, DjAdminViewMixin
Active plugins: djadmin.plugins.contrib_auth, examples.webshop, djadmin_formset, djadmin_classy_doc, djadmin_filters, djadmin.plugins.permissions, djadmin.plugins.core, djadmin.plugins.theme

View Information

Action
DeleteBulkAction
ModelAdmin
djadmin.options.ModelAdmin

View Construction

Base Class

djadmin.views.BulkDeleteView

Mixins

  • djadmin.plugins.permissions.mixins.PermissionMixin djadmin.plugins.permissions.djadmin_hooks
  • djadmin.plugins.core.mixins.DjAdminViewMixin djadmin.plugins.core.djadmin_hooks

Bound Methods from Action

  • get_template_names() from DeleteBulkAction
  • get_success_url() from DeleteBulkAction
  • get_queryset() from DeleteBulkAction

Method Resolution Order

  1. djadmin.factories.base.GenericDeleteBulkView
  2. djadmin.plugins.permissions.mixins.PermissionMixin djadmin.plugins.permissions.djadmin_hooks
  3. django.contrib.auth.mixins.UserPassesTestMixin
  4. django.contrib.auth.mixins.AccessMixin
  5. djadmin.plugins.core.mixins.DjAdminViewMixin djadmin.plugins.core.djadmin_hooks
  6. djadmin.views.BulkDeleteView base class from DeleteBulkAction
  7. django.views.generic.list.MultipleObjectMixin
  8. django.views.generic.edit.FormView
  9. django.views.generic.base.TemplateResponseMixin
  10. django.views.generic.edit.BaseFormView
  11. django.views.generic.edit.FormMixin
  12. django.views.generic.base.ContextMixin
  13. django.views.generic.edit.ProcessFormView
  14. django.views.generic.base.View

Attributes

Attribute Value Defined in
action DeleteBulkAction() djadmin.factories.base.GenericDeleteBulkView
admin_site AdminSite(name='docs_temp') djadmin.factories.base.GenericDeleteBulkView
allow_empty True django.views.generic.list.MultipleObjectMixin
content_type None django.views.generic.base.TemplateResponseMixin
context_object_name None django.views.generic.list.MultipleObjectMixin
extra_context None django.views.generic.base.ContextMixin
form_class None django.views.generic.edit.FormMixin
http_method_names ['get', 'post', 'put', 'patch', 'delete', 'head', 'option... django.views.generic.base.View
initial {} django.views.generic.edit.FormMixin
login_url None django.contrib.auth.mixins.AccessMixin
model None django.views.generic.list.MultipleObjectMixin
model_admin ModelAdmin() djadmin.factories.base.GenericDeleteBulkView
ordering None django.views.generic.list.MultipleObjectMixin
page_kwarg page django.views.generic.list.MultipleObjectMixin
paginate_by None django.views.generic.list.MultipleObjectMixin
paginate_orphans 0 django.views.generic.list.MultipleObjectMixin
paginator_class django.core.paginator.Paginator django.views.generic.list.MultipleObjectMixin
permission_denied_message django.contrib.auth.mixins.AccessMixin
prefix None django.views.generic.edit.FormMixin
queryset None django.views.generic.list.MultipleObjectMixin
raise_exception False django.contrib.auth.mixins.AccessMixin
redirect_field_name next django.contrib.auth.mixins.AccessMixin
response_class django.template.response.TemplateResponse django.views.generic.base.TemplateResponseMixin
success_url None django.views.generic.edit.FormMixin
template_engine None django.views.generic.base.TemplateResponseMixin
template_name None django.views.generic.base.TemplateResponseMixin
view_is_async False django.views.generic.base.View

Methods

__init__(self, **kwargs)

Defined in: <class 'django.views.generic.base.View'>

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

Source code in base.py line 54
    def __init__(self, **kwargs):
        """
        Constructor. Called in the URLconf; can contain helpful extra
        keyword arguments, and other things.
        """
        # Go through keyword arguments, and either save their values to our
        # instance, or raise an error.
        for key, value in kwargs.items():
            setattr(self, key, value)

as_view(**initkwargs) @classmethod

Defined in: <class 'django.views.generic.base.View'>

Main entry point for a request-response process.

Source code in base.py line 81
    @classonlymethod
    def as_view(cls, **initkwargs):
        """Main entry point for a request-response process."""
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError(
                    "The method name %s is not accepted as a keyword argument "
                    "to %s()." % (key, cls.__name__)
                )
            if not hasattr(cls, key):
                raise TypeError(
                    "%s() received an invalid keyword %r. as_view "
                    "only accepts arguments that are already "
                    "attributes of the class." % (cls.__name__, key)
                )

        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            self.setup(request, *args, **kwargs)
            if not hasattr(self, "request"):
                raise AttributeError(
                    "%s instance has no 'request' attribute. Did you override "
                    "setup() and forget to call super()?" % cls.__name__
                )
            return self.dispatch(request, *args, **kwargs)

        view.view_class = cls
        view.view_initkwargs = initkwargs

        # __name__ and __qualname__ are intentionally left unchanged as
        # view_class should be used to robustly determine the name of the view
        # instead.
        view.__doc__ = cls.__doc__
        view.__module__ = cls.__module__
        view.__annotations__ = cls.dispatch.__annotations__
        # Copy possible attributes set by decorators, e.g. @csrf_exempt, from
        # the dispatch method.
        view.__dict__.update(cls.dispatch.__dict__)

        # Mark the callback if the view class is async.
        if cls.view_is_async:
            markcoroutinefunction(view)

        return view

build_form(self, form=None)

Defined in: <class 'djadmin.plugins.core.mixins.DjAdminViewMixin'>

Build form class from layout or fields. Override in plugins to customize.

This method is called by get_form_class() when no explicit form_class is provided. The default implementation uses FormBuilder to create forms from layouts or fields.

Returns: ModelForm class ready for instantiation

Source code in mixins.py line 246
    def build_form(self, form=None):
        """
        Build form class from layout or fields. Override in plugins to customize.

        This method is called by get_form_class() when no explicit form_class is provided.
        The default implementation uses FormBuilder to create forms from layouts or fields.

        Returns:
            ModelForm class ready for instantiation
        """
        layout = self.get_layout()

        if layout:
            # Build from layout using FormBuilder
            print('using FormBuilder.from_layout')
            return FormBuilder.from_layout(layout, self.model, form_class=None)

        print('using FormBuilder.create_form')
        # No layout - build from fields

        fields = getattr(self, 'get_fields', lambda: '__all__')()
        return FormBuilder.create_form(self.model, fields=fields)

dispatch(self, request, *args, **kwargs)

Defined in: <class 'django.views.generic.base.View'>

Source code in base.py line 134
    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        if request.method.lower() in self.http_method_names:
            handler = getattr(
                self, request.method.lower(), self.http_method_not_allowed
            )
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)
Source code in mixins.py line 131
    def dispatch(self, request, *args, **kwargs):
        user_test_result = self.get_test_func()()
        if not user_test_result:
            return self.handle_no_permission()
        return super().dispatch(request, *args, **kwargs)

filtered_actions

Defined in: <class 'djadmin.plugins.core.mixins.DjAdminViewMixin'>

Filtered action lists by user permissions, cached on view instance.

For object-based views (UpdateView, DetailView, DeleteView), filters actions based on the specific object. For list views, filters at model level.

Results are cached on the view instance, which is per-request since Django creates a new view instance for each request. Combined with request-level caching in ModelAdmin.filter_actions(), this ensures actions are filtered only once per request.

Performance Impact: Without caching: Actions filtered multiple times per request With caching: Actions filtered once per request (view instance)

Returns: dict: Dictionary with filtered action lists: - filtered_general_actions - filtered_bulk_actions - filtered_record_actions

form_invalid(self, form)

Defined in: <class 'django.views.generic.edit.FormMixin'>

If the form is invalid, render the invalid form.

Source code in edit.py line 65
    def form_invalid(self, form):
        """If the form is invalid, render the invalid form."""
        return self.render_to_response(self.get_context_data(form=form))

form_valid(self, form)

Defined in: <class 'django.views.generic.edit.FormMixin'>

If the form is valid, redirect to the supplied URL.

Source code in edit.py line 61
    def form_valid(self, form):
        """If the form is valid, redirect to the supplied URL."""
        return HttpResponseRedirect(self.get_success_url())
Source code in views.py line 89
    def form_valid(self, form):
        """Delete selected objects."""
        selected_objects = form.cleaned_data['_selected_action']
        count = selected_objects.count()

        # Delete the objects
        selected_objects.delete()

        # Add success message
        messages.success(
            self.request,
            f'Successfully deleted {count} {self.model._meta.verbose_name_plural}',
        )

        return super().form_valid(form)

get(self, request, *args, **kwargs)

Defined in: <class 'django.views.generic.edit.ProcessFormView'>

Handle GET requests: instantiate a blank version of the form.

Source code in edit.py line 140
    def get(self, request, *args, **kwargs):
        """Handle GET requests: instantiate a blank version of the form."""
        return self.render_to_response(self.get_context_data())
Source code in views.py line 57
    def get(self, request, *args, **kwargs):
        """Handle GET request - show confirmation form."""
        # Set object_list for MultipleObjectMixin
        self.object_list = self.get_queryset()
        return super().get(request, *args, **kwargs)

get_allow_empty(self)

Defined in: <class 'django.views.generic.list.MultipleObjectMixin'>

Return True if the view should display empty lists and False if a 404 should be raised instead.

Source code in list.py line 106
    def get_allow_empty(self):
        """
        Return ``True`` if the view should display empty lists and ``False``
        if a 404 should be raised instead.
        """
        return self.allow_empty

get_context_data(self, **kwargs)

Defined in: <class 'django.views.generic.base.ContextMixin'>

Source code in base.py line 30
    def get_context_data(self, **kwargs):
        kwargs.setdefault("view", self)
        if self.extra_context is not None:
            kwargs.update(self.extra_context)
        return kwargs
Source code in edit.py line 69
    def get_context_data(self, **kwargs):
        """Insert the form into the context dict."""
        if "form" not in kwargs:
            kwargs["form"] = self.get_form()
        return super().get_context_data(**kwargs)
Source code in list.py line 122
    def get_context_data(self, *, object_list=None, **kwargs):
        """Get the context for this view."""
        queryset = object_list if object_list is not None else self.object_list
        page_size = self.get_paginate_by(queryset)
        context_object_name = self.get_context_object_name(queryset)
        if page_size:
            paginator, page, queryset, is_paginated = self.paginate_queryset(
                queryset, page_size
            )
            context = {
                "paginator": paginator,
                "page_obj": page,
                "is_paginated": is_paginated,
                "object_list": queryset,
            }
        else:
            context = {
                "paginator": None,
                "page_obj": None,
                "is_paginated": False,
                "object_list": queryset,
            }
        if context_object_name is not None:
            context[context_object_name] = queryset
        context.update(kwargs)
        return super().get_context_data(**context)
Source code in views.py line 79
    def get_context_data(self, **kwargs):
        """Add queryset and count to context."""
        context = super().get_context_data(**kwargs)

        # MultipleObjectMixin already adds object_list to context
        # Just add the count
        context['objects_count'] = context['object_list'].count()

        return context
Source code in mixins.py line 126
    def get_context_data(self, **kwargs):
        """
        Add standard admin context to all views.

        When bound to the view, self is the view instance which has:
        - self.action: Action instance
        - self.model: Model class
        - self.model_admin: ModelAdmin instance
        - self.admin_site: AdminSite instance
        - self.request: Current request
        """
        from djadmin.plugins import pm

        # Call super to get base context from Django CBV
        context = super().get_context_data(**kwargs)

        # Add request to context (needed for inclusion tags)
        context['request'] = self.request

        # Add standard admin context
        context['model'] = self.model
        context['opts'] = self.model._meta if self.model else None
        context['action'] = self.action
        context['model_admin'] = self.model_admin
        context['admin_site'] = self.admin_site

        # Add version information
        context['djadmin_version'] = djadmin.__version__
        context['django_version'] = django.get_version()

        # Add site-wide URLs
        try:
            context['index_url'] = reverse(f'{self.admin_site.name}:index')
        except Exception:
            context['index_url'] = '/'

        # Add site configuration
        context['site_header'] = self.admin_site.site_header
        context['site_title'] = self.admin_site.site_title
        context['index_title'] = self.admin_site.index_title

        # Add list URL (using admin_site namespace)
        # Skip for site-level actions (model=None)
        if self.model is not None:
            list_url_name = f'{self.model_admin.list_url_name}'
            context['list_url'] = self.admin_site.reverse(list_url_name)
        else:
            context['list_url'] = context.get('index_url', '/')

        # Add namespaced URL names for actions
        namespace = self.admin_site.name
        context['action_namespace'] = namespace

        # Add breadcrumbs
        context['breadcrumb_list'] = self._get_breadcrumbs()

        # Add assets from plugins
        assets = self._get_assets_from_plugins()
        context['assets'] = assets

        # Add sidebar widgets for template rendering
        sidebar_widgets = self._get_sidebar_widgets_for_template()
        context['sidebar_widgets'] = sidebar_widgets

        # Add column header icons for list views
        column_header_icons = self._get_column_header_icons()
        context['column_header_icons'] = column_header_icons

        # Add filtered actions to context (permission-checked)
        # This ensures all views (ListView, UpdateView, CreateView, etc.) get filtered actions
        if self.model is not None and self.model_admin is not None:
            # Add unfiltered action lists (for template tag use in ListView)
            context['general_actions'] = self.model_admin.general_actions
            context['bulk_actions'] = self.model_admin.bulk_actions
            context['record_actions'] = self.model_admin.record_actions

            # Add filtered action lists (for use in templates)
            context.update(self.filtered_actions)

        # Allow plugins to add more context
        plugin_contexts = pm.hook.djadmin_add_context_data(
            context=context,
            request=self.request,
            view=self,
        )

        for plugin_context in plugin_contexts:
            if plugin_context:
                context.update(plugin_context)

        if settings.DEBUG:
            # List loaded plugins for debugging
            # djp.PluginManager wraps pluggy, access the underlying manager
            try:
                # Get plugins from the underlying pluggy manager
                if hasattr(pm, '_pm'):
                    # djp stores the pluggy manager as _pm
                    plugins = pm._pm.get_plugins()
                elif hasattr(pm, 'get_plugins'):
                    plugins = pm.get_plugins()
                else:
                    # Fallback: just note that we couldn't list plugins
                    plugins = ['(plugin listing not available)']

                context['debug_loaded_plugins'] = [str(plugin) for plugin in plugins]
            except Exception as e:
                context['debug_loaded_plugins'] = [f'Error listing plugins: {e}']

            # Debug: Show view's MRO (Method Resolution Order) to see which mixins are applied
            context['debug_view_mro'] = [cls.__name__ for cls in self.__class__.__mro__[:10]]

            # Debug: Show form class being used
            if hasattr(self, 'form_class'):
                context['debug_form_class'] = str(self.form_class)

            # Debug: Show action class hierarchy
            context['debug_action_mro'] = [cls.__name__ for cls in self.action.__class__.__mro__[:10]]

        return context

get_context_object_name(self, object_list)

Defined in: <class 'django.views.generic.list.MultipleObjectMixin'>

Get the name of the item to be used in the context.

Source code in list.py line 113
    def get_context_object_name(self, object_list):
        """Get the name of the item to be used in the context."""
        if self.context_object_name:
            return self.context_object_name
        elif hasattr(object_list, "model"):
            return "%s_list" % object_list.model._meta.model_name
        else:
            return None

get_form(self, form_class=None)

Defined in: <class 'django.views.generic.edit.FormMixin'>

Return an instance of the form to be used in this view.

Source code in edit.py line 33
    def get_form(self, form_class=None):
        """Return an instance of the form to be used in this view."""
        if form_class is None:
            form_class = self.get_form_class()
        return form_class(**self.get_form_kwargs())

get_form_class(self)

Defined in: <class 'django.views.generic.edit.FormMixin'>

Return the form class to use.

Source code in edit.py line 29
    def get_form_class(self):
        """Return the form class to use."""
        return self.form_class
Source code in views.py line 31
    def get_form_class(self):
        """
        Get form class for bulk delete.

        Auto-generates a form with ModelMultipleChoiceField if not provided.
        """
        if self.form_class:
            return self.form_class

        # Auto-generate form with ModelMultipleChoiceField
        # Use _selected_action to match ListView's checkbox name
        class BulkDeleteForm(forms.Form):
            _selected_action = forms.ModelMultipleChoiceField(
                queryset=self.model.objects.all(),
                widget=forms.MultipleHiddenInput,
                required=True,
            )

        return BulkDeleteForm

get_form_kwargs(self)

Defined in: <class 'django.views.generic.edit.FormMixin'>

Return the keyword arguments for instantiating the form.

Source code in edit.py line 39
    def get_form_kwargs(self):
        """Return the keyword arguments for instantiating the form."""
        kwargs = {
            "initial": self.get_initial(),
            "prefix": self.get_prefix(),
        }

        if self.request.method in ("POST", "PUT"):
            kwargs.update(
                {
                    "data": self.request.POST,
                    "files": self.request.FILES,
                }
            )
        return kwargs
Source code in views.py line 69
    def get_form_kwargs(self):
        """Add selected objects to form kwargs."""
        kwargs = super().get_form_kwargs()

        # For GET requests, populate initial data with object_list
        if self.request.method == 'GET':
            kwargs['initial'] = {'_selected_action': self.object_list}

        return kwargs

get_initial(self)

Defined in: <class 'django.views.generic.edit.FormMixin'>

Return the initial data to use for forms on this view.

Source code in edit.py line 21
    def get_initial(self):
        """Return the initial data to use for forms on this view."""
        return self.initial.copy()

get_login_url(self)

Defined in: <class 'django.contrib.auth.mixins.AccessMixin'>

Override this method to override the login_url attribute.

Source code in mixins.py line 21
    def get_login_url(self):
        """
        Override this method to override the login_url attribute.
        """
        login_url = self.login_url or settings.LOGIN_URL
        if not login_url:
            raise ImproperlyConfigured(
                f"{self.__class__.__name__} is missing the login_url attribute. Define "
                f"{self.__class__.__name__}.login_url, settings.LOGIN_URL, or override "
                f"{self.__class__.__name__}.get_login_url()."
            )
        return str(login_url)

get_object(self, queryset=None)

Defined in: <class 'djadmin.plugins.permissions.mixins.PermissionMixin'>

Override to check object permissions after fetching.

Source code in mixins.py line 39
    def get_object(self, queryset=None):
        """Override to check object permissions after fetching."""
        obj = super().get_object(queryset)

        # Get permission class from action or model_admin
        permission_class = self._get_permission_class()

        if permission_class is not None:
            # Check object permission
            if not permission_class.has_object_permission(self, obj):
                raise PermissionDenied(f'You do not have permission to access this {obj._meta.verbose_name}.')

        return obj

get_ordering(self)

Defined in: <class 'django.views.generic.list.MultipleObjectMixin'>

Return the field or fields to use for ordering the queryset.

Source code in list.py line 49
    def get_ordering(self):
        """Return the field or fields to use for ordering the queryset."""
        return self.ordering

get_paginate_by(self, queryset)

Defined in: <class 'django.views.generic.list.MultipleObjectMixin'>

Get the number of items to paginate by, or None for no pagination.

Source code in list.py line 81
    def get_paginate_by(self, queryset):
        """
        Get the number of items to paginate by, or ``None`` for no pagination.
        """
        return self.paginate_by

get_paginate_orphans(self)

Defined in: <class 'django.views.generic.list.MultipleObjectMixin'>

Return the maximum number of orphans extend the last page by when paginating.

Source code in list.py line 99
    def get_paginate_orphans(self):
        """
        Return the maximum number of orphans extend the last page by when
        paginating.
        """
        return self.paginate_orphans

get_paginator(self, queryset, per_page, orphans=0, allow_empty_first_page=True, **kwargs)

Defined in: <class 'django.views.generic.list.MultipleObjectMixin'>

Return an instance of the paginator for this view.

Source code in list.py line 87
    def get_paginator(
        self, queryset, per_page, orphans=0, allow_empty_first_page=True, **kwargs
    ):
        """Return an instance of the paginator for this view."""
        return self.paginator_class(
            queryset,
            per_page,
            orphans=orphans,
            allow_empty_first_page=allow_empty_first_page,
            **kwargs,
        )

get_permission_denied_message(self)

Defined in: <class 'django.contrib.auth.mixins.AccessMixin'>

Override this method to override the permission_denied_message attribute.

Source code in mixins.py line 34
    def get_permission_denied_message(self):
        """
        Override this method to override the permission_denied_message attribute.
        """
        return self.permission_denied_message

get_prefix(self)

Defined in: <class 'django.views.generic.edit.FormMixin'>

Return the prefix to use for forms.

Source code in edit.py line 25
    def get_prefix(self):
        """Return the prefix to use for forms."""
        return self.prefix

get_queryset(self)

Defined in: <class 'django.views.generic.list.MultipleObjectMixin'>

Return the list of items for this view.

The return value must be an iterable and may be an instance of QuerySet in which case QuerySet specific behavior will be enabled.

Source code in list.py line 22
    def get_queryset(self):
        """
        Return the list of items for this view.

        The return value must be an iterable and may be an instance of
        `QuerySet` in which case `QuerySet` specific behavior will be enabled.
        """
        if self.queryset is not None:
            queryset = self.queryset
            if isinstance(queryset, QuerySet):
                queryset = queryset.all()
        elif self.model is not None:
            queryset = self.model._default_manager.all()
        else:
            raise ImproperlyConfigured(
                "%(cls)s is missing a QuerySet. Define "
                "%(cls)s.model, %(cls)s.queryset, or override "
                "%(cls)s.get_queryset()." % {"cls": self.__class__.__name__}
            )
        ordering = self.get_ordering()
        if ordering:
            if isinstance(ordering, str):
                ordering = (ordering,)
            queryset = queryset.order_by(*ordering)

        return queryset
Source code in views.py line 51
    def get_queryset(self):
        """Get queryset of objects to delete."""
        # Get PKs from request (either GET or POST)
        pks = self.request.POST.getlist('_selected_action') or self.request.GET.getlist('_selected_action')
        return self.model.objects.filter(pk__in=pks)

get_redirect_field_name(self)

Defined in: <class 'django.contrib.auth.mixins.AccessMixin'>

Override this method to override the redirect_field_name attribute.

Source code in mixins.py line 40
    def get_redirect_field_name(self):
        """
        Override this method to override the redirect_field_name attribute.
        """
        return self.redirect_field_name

get_success_url(self)

Defined in: <class 'django.views.generic.edit.FormMixin'>

Return the URL to redirect to after processing a valid form.

Source code in actions.py line 650
    def get_success_url(self):
        """
        Redirect to list view after creation.

        When bound to the view, self is the view instance which has:
        - self.object: The created object
        - self.request: The current request
        """
        opts = self.model._meta
        return self.admin_site.reverse(f'{opts.app_label}_{opts.model_name}_list')
Source code in base.py line 650
    def get_success_url(self):
        """
        Redirect to list view after creation.

        When bound to the view, self is the view instance which has:
        - self.object: The created object
        - self.request: The current request
        """
        opts = self.model._meta
        return self.admin_site.reverse(f'{opts.app_label}_{opts.model_name}_list')

get_template_names(self)

Defined in: <class 'django.views.generic.base.TemplateResponseMixin'>

Return a list of template names to be used for the request. Must return a list. May not be called if render_to_response() is overridden.

Source code in actions.py line 175
    def get_template_names(self):
        """
        Get template names as a list (Django CBV expects plural method).

        This wraps get_template_name() and ensures the result is a list.

        Returns:
            List of template path strings
        """
        template_names = []

        if model_name := getattr(getattr(self.model, '_meta', None), 'model_name', None):
            template_names.append(f'djadmin/{self.model._meta.app_label}/{model_name}_{self.action.action_name}.html')
        template_names.append(f'djadmin/actions/{self.action.action_name}.html')

        return template_names
Source code in base.py line 175
    def get_template_names(self):
        """
        Get template names as a list (Django CBV expects plural method).

        This wraps get_template_name() and ensures the result is a list.

        Returns:
            List of template path strings
        """
        template_names = []

        if model_name := getattr(getattr(self.model, '_meta', None), 'model_name', None):
            template_names.append(f'djadmin/{self.model._meta.app_label}/{model_name}_{self.action.action_name}.html')
        template_names.append(f'djadmin/actions/{self.action.action_name}.html')

        return template_names

get_test_func(self)

Defined in: <class 'django.contrib.auth.mixins.UserPassesTestMixin'>

Override this method to use a different test_func method.

Source code in mixins.py line 125
    def get_test_func(self):
        """
        Override this method to use a different test_func method.
        """
        return self.test_func

handle_no_permission(self)

Defined in: <class 'django.contrib.auth.mixins.AccessMixin'>

Source code in mixins.py line 46
    def handle_no_permission(self):
        if self.raise_exception or self.request.user.is_authenticated:
            raise PermissionDenied(self.get_permission_denied_message())

        path = self.request.build_absolute_uri()
        resolved_login_url = resolve_url(self.get_login_url())
        # If the login url is the same scheme and net location then use the
        # path as the "next" url.
        login_scheme, login_netloc = urlsplit(resolved_login_url)[:2]
        current_scheme, current_netloc = urlsplit(path)[:2]
        if (not login_scheme or login_scheme == current_scheme) and (
            not login_netloc or login_netloc == current_netloc
        ):
            path = self.request.get_full_path()
        return redirect_to_login(
            path,
            resolved_login_url,
            self.get_redirect_field_name(),
        )

http_method_not_allowed(self, request, *args, **kwargs)

Defined in: <class 'django.views.generic.base.View'>

Source code in base.py line 146
    def http_method_not_allowed(self, request, *args, **kwargs):
        response = HttpResponseNotAllowed(self._allowed_methods())
        log_response(
            "Method Not Allowed (%s): %s",
            request.method,
            request.path,
            response=response,
            request=request,
        )

        if self.view_is_async:

            async def func():
                return response

            return func()
        else:
            return response

options(self, request, *args, **kwargs)

Defined in: <class 'django.views.generic.base.View'>

Handle responding to requests for the OPTIONS HTTP verb.

Source code in base.py line 165
    def options(self, request, *args, **kwargs):
        """Handle responding to requests for the OPTIONS HTTP verb."""
        response = HttpResponse()
        response.headers["Allow"] = ", ".join(self._allowed_methods())
        response.headers["Content-Length"] = "0"

        if self.view_is_async:

            async def func():
                return response

            return func()
        else:
            return response

paginate_queryset(self, queryset, page_size)

Defined in: <class 'django.views.generic.list.MultipleObjectMixin'>

Paginate the queryset, if needed.

Source code in list.py line 53
    def paginate_queryset(self, queryset, page_size):
        """Paginate the queryset, if needed."""
        paginator = self.get_paginator(
            queryset,
            page_size,
            orphans=self.get_paginate_orphans(),
            allow_empty_first_page=self.get_allow_empty(),
        )
        page_kwarg = self.page_kwarg
        page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1
        try:
            page_number = int(page)
        except ValueError:
            if page == "last":
                page_number = paginator.num_pages
            else:
                raise Http404(
                    _("Page is not “last”, nor can it be converted to an int.")
                )
        try:
            page = paginator.page(page_number)
            return (paginator, page, page.object_list, page.has_other_pages())
        except InvalidPage as e:
            raise Http404(
                _("Invalid page (%(page_number)s): %(message)s")
                % {"page_number": page_number, "message": str(e)}
            )

post(self, request, *args, **kwargs)

Defined in: <class 'django.views.generic.edit.ProcessFormView'>

Handle POST requests: instantiate a form instance with the passed POST variables and then check if it's valid.

Source code in edit.py line 144
    def post(self, request, *args, **kwargs):
        """
        Handle POST requests: instantiate a form instance with the passed
        POST variables and then check if it's valid.
        """
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)
Source code in views.py line 63
    def post(self, request, *args, **kwargs):
        """Handle POST request - process form and delete."""
        # Set object_list for MultipleObjectMixin
        self.object_list = self.get_queryset()
        return super().post(request, *args, **kwargs)

put(self, *args, **kwargs)

Defined in: <class 'django.views.generic.edit.ProcessFormView'>

PUT is a valid HTTP verb for creating (with a known URL) or editing an
object, note that browsers only support POST for now.
Source code in edit.py line 157
    def put(self, *args, **kwargs):
        return self.post(*args, **kwargs)

render_to_response(self, context, **response_kwargs)

Defined in: <class 'django.views.generic.base.TemplateResponseMixin'>

Return a response, using the response_class for this view, with a template rendered with the given context.

Pass response_kwargs to the constructor of the response class.

Source code in base.py line 192
    def render_to_response(self, context, **response_kwargs):
        """
        Return a response, using the `response_class` for this view, with a
        template rendered with the given context.

        Pass response_kwargs to the constructor of the response class.
        """
        response_kwargs.setdefault("content_type", self.content_type)
        return self.response_class(
            request=self.request,
            template=self.get_template_names(),
            context=context,
            using=self.template_engine,
            **response_kwargs,
        )

setup(self, request, *args, **kwargs)

Defined in: <class 'django.views.generic.base.View'>

Initialize attributes shared by all view methods.

Source code in base.py line 126
    def setup(self, request, *args, **kwargs):
        """Initialize attributes shared by all view methods."""
        if hasattr(self, "get") and not hasattr(self, "head"):
            self.head = self.get
        self.request = request
        self.args = args
        self.kwargs = kwargs

test_func(self)

Defined in: <class 'django.contrib.auth.mixins.UserPassesTestMixin'>

Source code in mixins.py line 118
    def test_func(self):
        raise NotImplementedError(
            "{} is missing the implementation of the test_func() method.".format(
                self.__class__.__name__
            )
        )
Source code in mixins.py line 16
    def test_func(self):
        """
        Permission check method for UserPassesTestMixin.

        This method is called by UserPassesTestMixin to check if the user
        has permission to access the view.

        Returns:
            bool: True if user has permission, False otherwise
        """
        # Get permission from action or model_admin
        perm = self._get_permission_class()

        if perm is None:
            # None means no permission enforcement (allow all access)
            # This happens when:
            # 1. Explicitly set to None on ModelAdmin or Action
            # 2. No model_admin exists (site-level views like DashboardAction)
            return True

        # Execute permission with view (self is the view)
        return perm(self)

Fields

Field Type Related To
__dict__ getset_descriptor -
__weakref__ getset_descriptor -