django-object-actions
django-object-actions is a Django app that provides an easy way to add custom object-level actions to your Django admin interface. Instead of model-wide actions, these are specific to individual objects, appearing on the change page. The current version is 5.0.0, with minor releases occurring every few months and major breaking changes typically yearly, often tied to Django or Python version support updates.
Warnings
- breaking Older Python versions are no longer supported. v2.0.0 dropped Python 2, v3.0.0 dropped Python 3.4, and v4.0.0 dropped Python 3.6. The current version (v5.0.0) requires Python >= 3.9.
- gotcha Object action methods must accept at least `request` and `obj` as arguments. An optional third argument `form` can be added if your action needs to interact with the model's admin form.
- gotcha By default, object actions require the user to have 'change' permissions for the model. If a user lacks this permission, the action button will not be visible. Custom permission checks can be implemented.
- gotcha It's crucial for object action methods to return an `HttpResponse` (e.g., `HttpResponseRedirect`) or `None`. If `None` is returned, the user will remain on the same page. Not returning a valid HTTP response can lead to unexpected behavior.
- gotcha While listing action names in the `objectactions` attribute still works, the `@object_action` decorator (introduced in v4.1.0) is the recommended modern approach as it allows specifying a `label`, `description`, `attrs`, and `permission_required` directly on the method.
Install
-
pip install django-object-actions
Imports
- ObjectActions
from object_actions import ObjectActions
- object_action
from object_actions import object_action
Quickstart
import os
from django.contrib import admin
from django.db import models
from django.http import HttpResponseRedirect
from object_actions import ObjectActions, object_action
# Define a simple model for demonstration
class MyModel(models.Model):
name = models.CharField(max_length=100)
value = models.IntegerField(default=0)
def __str__(self):
return self.name
class Meta:
app_label = 'myapp' # Ensure app_label is set for isolated example
# Configure admin with object actions
class MyModelAdmin(ObjectActions, admin.ModelAdmin):
list_display = ('name', 'value')
objectactions = ['reset_value_legacy'] # Old way to register actions
def reset_value_legacy(self, request, obj):
obj.value = 0
obj.save()
self.message_user(request, f"Value for {obj.name} reset to 0.")
return HttpResponseRedirect(request.get_full_path())
@object_action(label='Increment Value', description='Increments the object\'s value by 1.')
def increment_value_decorator(self, request, obj):
obj.value += 1
obj.save()
self.message_user(request, f"Value for {obj.name} incremented to {obj.value}.")
return HttpResponseRedirect(request.get_full_path())
# In a real Django project, you would register this in myapp/admin.py
# For this standalone example, we just define it.
# Example usage (conceptual, for actual setup you need a Django project):
# 1. Add 'object_actions' to INSTALLED_APPS in settings.py
# 2. Add 'myapp' to INSTALLED_APPS (if MyModel is in myapp)
# 3. In myapp/admin.py:
# admin.site.register(MyModel, MyModelAdmin)
print("To use, add 'object_actions' to INSTALLED_APPS and register your ModelAdmin inheriting from ObjectActions.")
print("Define methods on your ModelAdmin and list them in 'objectactions' or use the @object_action decorator.")