or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-django-object-actions

A Django app for adding object tools for models in the admin

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/django-object-actions@5.0.x

To install, run

npx @tessl/cli install tessl/pypi-django-object-actions@5.0.0

index.mddocs/

Django Object Actions

A Django app for adding object tools for models in the admin interface. Django Object Actions extends Django's admin action framework to work on individual model instances in addition to querysets, enabling custom actions on both change and changelist views.

Package Information

  • Package Name: django-object-actions
  • Language: Python
  • Installation: pip install django-object-actions
  • Django Compatibility: Django admin framework required
  • Python Compatibility: 3.9+

Core Imports

from django_object_actions import DjangoObjectActions, action, takes_instance_or_queryset

For advanced use cases:

from django_object_actions import BaseDjangoObjectActions

Basic Usage

from django.contrib import admin
from django_object_actions import DjangoObjectActions, action

class ArticleAdmin(DjangoObjectActions, admin.ModelAdmin):
    @action(label="Publish", description="Submit this article")
    def publish_this(self, request, obj):
        # Your custom logic here
        obj.status = 'published'
        obj.save()
        self.message_user(request, f"Published {obj.title}")

    change_actions = ('publish_this',)
    changelist_actions = ()

admin.site.register(Article, ArticleAdmin)

Setup Requirements

  1. Add to Django settings:
INSTALLED_APPS = [
    # ... other apps
    'django_object_actions',
    # ... other apps
]
  1. Inherit from DjangoObjectActions mixin in your ModelAdmin classes.

Capabilities

Admin Mixin Classes

Core mixin classes that extend Django ModelAdmin to support object actions.

BaseDjangoObjectActions

Base mixin providing object action functionality without default templates.

class BaseDjangoObjectActions:
    """
    ModelAdmin mixin to add new actions just like adding admin actions.
    
    Attributes:
    - change_actions: list of str - Action names for change view
    - changelist_actions: list of str - Action names for changelist view
    - tools_view_name: str - URL name for the actions view
    """
    
    change_actions = []
    changelist_actions = []
    tools_view_name = None
    
    def get_change_actions(self, request, object_id, form_url):
        """Override to customize what actions appear in change view."""
        
    def get_changelist_actions(self, request):
        """Override to customize what actions appear in changelist view."""

DjangoObjectActions

Main mixin that includes admin templates and extends BaseDjangoObjectActions.

class DjangoObjectActions(BaseDjangoObjectActions):
    """
    Complete mixin with templates for Django admin object actions.
    
    Attributes:
    - change_form_template: str - Template for change form
    - change_list_template: str - Template for changelist
    """
    
    change_form_template = "django_object_actions/change_form.html"
    change_list_template = "django_object_actions/change_list.html"

Action Decorators

Decorators for enhancing action functions with metadata and behavior.

@action Decorator

Adds metadata and behavior configuration to action functions.

def action(
    function=None,
    *,
    permissions=None,
    description=None,
    label=None,
    attrs=None,
    methods=('GET', 'POST'),
    button_type='a'
):
    """
    Add attributes to an action function.
    
    Parameters:
    - permissions: list of str - Required permissions
    - description: str - Tooltip description for the button
    - label: str - Display label for the button (defaults to function name)
    - attrs: dict - HTML attributes for the button element
    - methods: tuple - Allowed HTTP methods (default: ('GET', 'POST'))
    - button_type: str - Button type ('a' for link, 'form' for form submission)
    
    Returns:
    Decorated function with added attributes
    """

Usage Examples:

@action(label="Publish Article", description="Mark this article as published")
def publish_article(self, request, obj):
    obj.status = 'published'
    obj.save()

@action(
    permissions=['publish'],
    description='Submit for publication',
    attrs={'class': 'btn-primary'},
    methods=('POST',),
    button_type='form'
)
def submit_for_publication(self, request, obj):
    obj.submit_for_review()

@takes_instance_or_queryset Decorator

Converts admin actions to work with both individual objects and querysets.

def takes_instance_or_queryset(func):
    """
    Make standard Django admin actions compatible with object actions.
    
    Converts single model instances to querysets, allowing reuse of
    existing admin actions as object actions.
    
    Parameters:
    - func: function - Admin action function that expects a queryset
    
    Returns:
    Decorated function that works with both instances and querysets
    """

Usage Example:

@takes_instance_or_queryset
def mark_as_featured(self, request, queryset):
    queryset.update(featured=True)
    self.message_user(request, f"Marked {queryset.count()} items as featured")

# Can be used in both contexts:
change_actions = ['mark_as_featured']  # Works on single objects
actions = ['mark_as_featured']         # Works on querysets

Action Implementation Patterns

Change Actions (Single Object)

Actions that operate on individual model instances in the change view.

class MyModelAdmin(DjangoObjectActions, admin.ModelAdmin):
    def my_change_action(self, request, obj):
        """
        Action function for change view.
        
        Parameters:
        - request: HttpRequest - Django request object
        - obj: Model instance - The object being acted upon
        
        Returns:
        - None: Redirects back to change view
        - HttpResponse: Custom response (redirect, render, etc.)
        """
        # Your logic here
        obj.some_field = 'new_value'
        obj.save()
        
        # Optional: Send message to user
        self.message_user(request, "Action completed successfully")
        
        # Optional: Custom redirect
        # return HttpResponseRedirect('/custom/url/')
    
    change_actions = ('my_change_action',)

Changelist Actions (Queryset)

Actions that operate on querysets in the changelist view.

class MyModelAdmin(DjangoObjectActions, admin.ModelAdmin):
    def my_changelist_action(self, request, queryset):
        """
        Action function for changelist view.
        
        Parameters:
        - request: HttpRequest - Django request object
        - queryset: QuerySet - The selected objects
        
        Returns:
        - None: Redirects back to changelist view
        - HttpResponse: Custom response
        """
        # Bulk operation
        updated = queryset.update(status='processed')
        self.message_user(request, f"Updated {updated} items")
    
    changelist_actions = ('my_changelist_action',)

Dynamic Action Control

Control which actions are available based on context.

class MyModelAdmin(DjangoObjectActions, admin.ModelAdmin):
    def get_change_actions(self, request, object_id, form_url):
        """
        Dynamically determine available change actions.
        
        Parameters:
        - request: HttpRequest - Current request
        - object_id: str - Primary key of the object
        - form_url: str - URL of the change form
        
        Returns:
        list of str - Action names to display
        """
        actions = list(super().get_change_actions(request, object_id, form_url))
        
        # Example: Remove action based on user permissions
        if not request.user.is_superuser:
            actions = [a for a in actions if a != 'dangerous_action']
        
        # Example: Remove action based on object state
        obj = self.model.objects.get(pk=object_id)
        if obj.status == 'published':
            actions = [a for a in actions if a != 'publish_action']
        
        return actions
    
    def get_changelist_actions(self, request):
        """
        Dynamically determine available changelist actions.
        
        Parameters:
        - request: HttpRequest - Current request
        
        Returns:
        list of str - Action names to display
        """
        actions = list(super().get_changelist_actions(request))
        
        # Example: Role-based action availability
        if request.user.groups.filter(name='editors').exists():
            actions.append('editor_special_action')
        
        return actions

Advanced Usage Patterns

Custom Response Handling

Actions can return custom HTTP responses for complex workflows.

def complex_action(self, request, obj):
    """Action with custom response handling."""
    from django.shortcuts import render
    from django.http import HttpResponseRedirect
    
    if request.method == 'POST':
        # Process the action
        obj.process_complex_operation()
        self.message_user(request, "Operation completed")
        return None  # Redirect back to change view
    
    # Show confirmation page
    return render(request, 'admin/confirm_complex_action.html', {
        'object': obj,
        'title': 'Confirm Complex Action'
    })

Integration with Existing Admin Actions

Reuse existing admin actions as object actions.

class MyModelAdmin(DjangoObjectActions, admin.ModelAdmin):
    def bulk_update_status(self, request, queryset):
        """Standard admin action."""
        queryset.update(status='updated')
        self.message_user(request, f"Updated {queryset.count()} items")
    
    @takes_instance_or_queryset
    def single_update_status(self, request, queryset):
        """Same logic, works for both single objects and querysets."""
        return self.bulk_update_status(request, queryset)
    
    # Available in both contexts
    actions = ['bulk_update_status']
    change_actions = ['single_update_status']
    changelist_actions = ['bulk_update_status']

HTML Attribute Customization

Customize button appearance and behavior with HTML attributes.

@action(
    label="Delete Safely",
    description="Safely delete this item with confirmation",
    attrs={
        'class': 'btn btn-danger',
        'onclick': 'return confirm("Are you sure?");',
        'data-toggle': 'tooltip',
        'data-placement': 'top'
    }
)
def safe_delete(self, request, obj):
    obj.delete()
    self.message_user(request, "Item deleted successfully")

Error Handling

The framework handles common error scenarios:

  • Invalid action names: Raises Http404 if action doesn't exist
  • HTTP method restrictions: Returns HttpResponseNotAllowed for invalid methods
  • Permission checking: Integrates with Django admin's permission system
  • URL parameter handling: Properly unquotes special characters in primary keys

Template Integration

Django Object Actions provides three templates that extend Django's admin templates:

  • django_object_actions/change_form.html - Adds action buttons to change view
  • django_object_actions/change_list.html - Adds action buttons to changelist view
  • django_object_actions/action_trigger.html - Renders individual action buttons

These templates automatically integrate with your existing admin customizations and preserve all Django admin functionality.