Base Actions (Custom Actions)
Developer guide for the Enezaframework. Part of the Developer documentation.
Table of Contents
- Overview
- The
BaseActionContract - Writing an Action
- Surfacing an Action on a Detail View
- Generated URL
- Change History
- Related Guides
Overview
A custom action performs a one-off operation on a model instance — post an invoice, approve an
expense, change a status. Actions are implemented as small views that subclass BaseAction and are
referenced from a detail view's action_list (or print_actions).
flowchart LR
DETAIL[Detail view<br/>action_list entry] --> BUTTON[Action button / menu item]
BUTTON --> URL["Generated URL<br/>{action_name}_action"]
URL --> ACTION[BaseAction.process_action(pk)]
ACTION --> REDIRECT[Redirect back to detail view]The BaseAction Contract
class BaseAction(View) — defined in enezaframework/views/baseactions.py.
| Member | Purpose |
|---|---|
model |
The model the action operates on. Required. |
action_name |
Identifier used to build the URL name. Required. |
url_name |
Optional URL prefix override. |
view_type |
Set to "action" by the base class. |
process_action(self, pk) |
Your business logic. Raises NotImplementedError if not overridden. |
BaseAction.post() reads the pk from the URL kwargs (or the POST body), calls process_action(pk),
then redirects to the record's detail view. The base class is wrapped with login_required.
Writing an Action
from enezaframework.views import BaseAction
from enezaframework.utils import auto_url_register
from accountpayable.models import VendorTable
@auto_url_register
class PrintNameAction(BaseAction):
model = VendorTable
action_name = "printname"
def process_action(self, pk):
vendor = self.model.objects.get(pk=pk)
# ... business logic: print, post, notify, ...
return vendor
auto_url_register exempts View subclasses from the model requirement, but you should still set
model so BaseAction can resolve the detail URL after the action runs.
Surfacing an Action on a Detail View
Reference the action from a detail view's action_list. The url value is a partial identifier; the
framework builds the full app_name:... URL name.
from enezaframework.views import BaseDetailView
from enezaframework.utils import auto_url_register
from accountpayable.models import VendorTable
@auto_url_register
class VendorTableDetailView(BaseDetailView):
model = VendorTable
action_list = [
{
"name": "Print Name",
"icon": "DocumentPlus",
"url": "printname",
"confirm_message": "Are you sure you want to print this name?",
},
]
def detail_ui_view(self):
return [
{
"name": "Basic Information",
"icon": "Home",
"Fieldcolumns": [{"fields": ["vendorno", "searchname"]}],
},
]
print_actions uses the same shape for print/report actions and is rendered through the detail view's
print dropdown. Both action_list and print_actions are class attributes on BaseDetailView.
Generated URL
For a view_type of action, get_registered_urls produces:
| Pattern | URL name |
|---|---|
{Action Name Title}/<str:pk> |
{action_name}_action |
The path segment is the action name converted to title case (underscores replaced, words capitalized).
For action_name = "printname" the URL name is printname_action.
The user is solely responsible for testing and validating the action; the developer/agent does not run the application.
Change History
Dated changes that affect this guide, taken from
docs/Release note/CHANGELOG.md and the release notes. For the
complete history, see the changelog.
| Date | Version | What changed |
|---|---|---|
| 2026-07-02 | 0.2.11 | Nav actions toolbar gained the data-extraction menu include (navaextractionmenu.html in navactions.html). |
| 2026-07-10 | 0.2.16 | BaseAction (and other non-UrlMixin views) gained optional url_name support. |