BaseAction¶
BaseAction
¶
djadmin.actions.base.BaseAction
Base class for all actions in djadmin.
Actions represent operations that can be performed on models. They are the foundation of djadmin's extensible architecture, combining with action type mixins (GeneralActionMixin, BulkActionMixin, RecordActionMixin) and view type mixins (TemplateViewActionMixin, FormViewActionMixin) to create complete views.
Class Attributes
| Attribute | Type | Description |
|---|---|---|
label |
str |
Display name for the action. Required. |
icon |
str |
Icon name/class for UI display. Optional. |
css_class |
str |
Additional CSS classes. Default: '' |
confirmation_required |
bool |
Show confirmation before execute. Default: False |
http_method |
str |
HTTP method ('GET' or 'POST'). Default: 'GET' |
django_permission_name |
str |
Permission name ('add', 'change', 'view', 'delete'). Default: 'view' |
permission_class |
- | Permission callable. Overrides ModelAdmin permission. Default: None |
Examples
Simple template action::
from djadmin.actions import BaseAction, GeneralActionMixin
from djadmin.actions.view_mixins import TemplateViewActionMixin
class HelpAction(GeneralActionMixin, TemplateViewActionMixin, BaseAction):
label = 'Help'
icon = 'question'
def get_template_name(self):
return 'myapp/help.html'
Form-based action::
from djadmin.actions import BaseAction, RecordActionMixin
from djadmin.actions.view_mixins import FormViewActionMixin
class DuplicateAction(RecordActionMixin, FormViewActionMixin, BaseAction):
label = 'Duplicate'
form_class = DuplicateForm
def form_valid(self, form):
# Create duplicate
return super().form_valid(form)
Action with custom permission::
class SecretAction(GeneralActionMixin, BaseAction):
label = 'Secret'
permission_class = IsSuperuser()
Notes
- Always combine with an action type mixin (General/Bulk/Record)
- Always combine with a view type mixin (TemplateView/FormView)
- The label attribute is required
- Actions are instantiated by ModelAdmin during registration
Method Resolution Order
djadmin.actions.base.BaseAction
Attributes
| Attribute | Value | Defined in |
|---|---|---|
__annotations__ |
{'label': <class 'str'>, 'icon': <class 'str'>, 'css_clas... |
djadmin.actions.base.BaseAction
|
confirmation_required |
False |
djadmin.actions.base.BaseAction
|
css_class |
|
djadmin.actions.base.BaseAction
|
django_permission_name |
view |
djadmin.actions.base.BaseAction
|
http_method |
GET |
djadmin.actions.base.BaseAction
|
icon |
None |
djadmin.actions.base.BaseAction
|
label |
None |
djadmin.actions.base.BaseAction
|
permission_class |
None |
djadmin.actions.base.BaseAction
|
Methods
__init__(self, model, model_admin, admin_site, permission_class=None)
Defined in:
<class 'djadmin.actions.base.BaseAction'>
Initialize action with model and admin context.
Args: model: The Django model class (optional, can be None for site-level actions) model_admin: The ModelAdmin instance (optional, can be None for site-level actions) admin_site: The AdminSite instance permission_class: Permission callable (overrides ModelAdmin global permission)
Source code
in base.py
line 84
def __init__(self, model, model_admin, admin_site, permission_class=None):
"""
Initialize action with model and admin context.
Args:
model: The Django model class (optional, can be None for site-level actions)
model_admin: The ModelAdmin instance (optional, can be None for site-level actions)
admin_site: The AdminSite instance
permission_class: Permission callable (overrides ModelAdmin global permission)
"""
self.model = model
self.model_admin = model_admin
self.admin_site = admin_site
# Override permission_class if provided
if permission_class is not None:
self.permission_class = permission_class
if self.label is None:
raise ValueError(f'{self.__class__.__name__} must define label')
__repr__(self)
Defined in:
<class 'djadmin.actions.base.BaseAction'>
Source code
in repr.py
line 37
def __repr__(self):
return _generate_repr(self)
action_name
@property
Defined in:
<class 'djadmin.actions.base.BaseAction'>
check_permission(self, request: django.http.request.HttpRequest, obj=None) -> bool
Defined in:
<class 'djadmin.actions.base.BaseAction'>
Check if user has permission to execute this action.
This method creates a minimal view instance with the request and action context, then calls the test_func() permission check. This allows actions to be filtered in templates and list views without actually executing them.
Args: request: The HTTP request with user information obj: Optional specific object instance for object-level permissions
Returns: bool: True if user has permission, False otherwise
Source code
in base.py
line 226
def check_permission(self, request: HttpRequest, obj=None) -> bool:
"""
Check if user has permission to execute this action.
This method creates a minimal view instance with the request and action
context, then calls the test_func() permission check. This allows actions
to be filtered in templates and list views without actually executing them.
Args:
request: The HTTP request with user information
obj: Optional specific object instance for object-level permissions
Returns:
bool: True if user has permission, False otherwise
"""
# Get the cached view class
view_class = self.view_class
# Create a minimal view instance with request context
view = view_class()
view.request = request
view.action = self
view.model = self.model
view.model_admin = self.model_admin
view.admin_site = self.admin_site
# Set object if provided (for object-level permissions)
if obj is not None:
view.object = obj
# Call test_func to check permission
# test_func is provided by PermissionMixin
if hasattr(view, 'test_func'):
return view.test_func()
# If no test_func, default to allow
return True
get_base_class(self)
Defined in:
<class 'djadmin.actions.base.BaseAction'>
Get view base class for this action.
Looks through MRO for view-type mixins that define base_class. This allows actions to specify their view type through mixins.
Example: class MyAction(FormViewActionMixin, BaseAction): pass
action.get_base_class() # Returns FormView
Returns: View class from mixin or TemplateView as fallback
Source code
in base.py
line 150
def get_base_class(self):
"""
Get view base class for this action.
Looks through MRO for view-type mixins that define base_class.
This allows actions to specify their view type through mixins.
Example:
class MyAction(FormViewActionMixin, BaseAction):
pass
action.get_base_class() # Returns FormView
Returns:
View class from mixin or TemplateView as fallback
"""
for base in self.__class__.__mro__:
if hasattr(base, 'base_class'):
return base.base_class
# Default fallback
from django.views.generic import TemplateView
return TemplateView
get_template_names(self)
Defined in:
<class 'djadmin.actions.base.BaseAction'>
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
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_url_name(self) -> str
Defined in:
<class 'djadmin.actions.base.BaseAction'>
Get URL name for this action (deprecated, use url_name property).
Returns: URL name string
Source code
in base.py
line 141
def get_url_name(self) -> str:
"""
Get URL name for this action (deprecated, use url_name property).
Returns:
URL name string
"""
return self.url_name
get_url_pattern(self) -> str
Defined in:
<class 'djadmin.actions.base.BaseAction'>
Get URL pattern for this action.
Override this to customize the URL pattern for the action. Default pattern is: {app_label}/{model_name}/{action__name}/
Returns: URL pattern string (without leading slash)
Source code
in base.py
line 128
def get_url_pattern(self) -> str:
"""
Get URL pattern for this action.
Override this to customize the URL pattern for the action.
Default pattern is: {app_label}/{model_name}/{action__name}/
Returns:
URL pattern string (without leading slash)
"""
opts = self.model._meta
return f'{opts.app_label}/{opts.model_name}/{self.action_name}/'
get_view_class(self)
Defined in:
<class 'djadmin.actions.base.BaseAction'>
Get the view class for this action via ViewFactory.
This method delegates to the cached view_class property to avoid recreating view classes on every call. Provided for backward compatibility and API consistency.
Returns: View class ready for .as_view()
Source code
in base.py
line 213
def get_view_class(self):
"""
Get the view class for this action via ViewFactory.
This method delegates to the cached view_class property to avoid
recreating view classes on every call. Provided for backward
compatibility and API consistency.
Returns:
View class ready for .as_view()
"""
return self.view_class
url_name
@property
Defined in:
<class 'djadmin.actions.base.BaseAction'>
Get URL name for this action.
Can be overridden by setting _url_name class attribute.
Returns: URL name string
view_class
Defined in:
<class 'djadmin.actions.base.BaseAction'>
Cached view class for this action.
The view class is created once via ViewFactory and cached for the lifetime of the action instance. This eliminates the overhead of recreating view classes on every permission check.
Performance Impact: Without caching: 10+ view class creations per ListView request With caching: 1 view class creation per action (first permission check)
Returns: View class ready for .as_view()
Fields
| Field | Type | Related To |
|---|---|---|
__dict__ |
getset_descriptor |
- |
__weakref__ |
getset_descriptor |
- |