Hook Reference¶
Complete reference of all available hooks in django-admin-deux.
Source:
djadmin/plugins/__init__.py
Feature Advertising¶
djadmin_provides_features()¶
Advertise features your plugin provides.
Returns: List[str] - Feature names
Example:
Usage: Features are validated at startup against ModelAdmin.FEATURE_INDICATORS.
Action Registration¶
djadmin_get_default_general_actions()¶
Provide default general actions (list-level actions, main entry points).
Returns: List[Type[BaseAction]] - Action classes
Example:
@hookimpl
def djadmin_get_default_general_actions():
from .actions import ExportAction
return [ExportAction]
Built-in: Core plugin provides ListAction and AddAction.
djadmin_get_default_bulk_actions()¶
Provide default bulk actions (operate on selected records).
Returns: List[Type[BaseAction]] - Action classes
Example:
@hookimpl
def djadmin_get_default_bulk_actions():
from .actions import BulkUpdateAction
return [BulkUpdateAction]
Built-in: Core plugin provides DeleteBulkAction.
djadmin_get_default_record_actions()¶
Provide default record actions (operate on single records).
Returns: List[Type[BaseAction]] - Action classes
Example:
@hookimpl
def djadmin_get_default_record_actions():
from .actions import DuplicateAction
return [DuplicateAction]
Built-in: Core plugin provides EditAction and DeleteAction.
djadmin_register_actions()¶
Register custom action classes with identifiers.
Returns: Dict[str, Type[BaseAction]] - Mapping of identifier to action class
Example:
@hookimpl
def djadmin_register_actions():
return {
'export_pdf': ExportPDFAction,
'send_email': SendEmailAction,
}
Usage: Allows referencing actions by string identifier in ModelAdmin configuration.
View Customization (Registry Pattern)¶
All view customization hooks use a registry pattern: they return dictionaries mapping action classes to values. The factory checks isinstance(action, key) for each key, allowing plugins to target specific action types or base classes.
djadmin_get_action_view_mixins(action)¶
Provide mixins for generated views.
Args:
- action - Action instance (for context)
Returns: Dict[Type, List[Type]] - Mapping of action classes to mixin lists
Example:
@hookimpl
def djadmin_get_action_view_mixins(action):
from djadmin.actions.view_mixins import ListActionMixin
from .mixins import SearchMixin
return {
ListActionMixin: [SearchMixin],
}
Built-in: Core plugin adds DjAdminViewMixin to all actions.
djadmin_get_action_view_base_class(action)¶
Override base view class for specific actions.
Args:
- action - Action instance
Returns: Dict[Type, Type] - Mapping of action classes to base view classes
Example:
@hookimpl
def djadmin_get_action_view_base_class(action):
return {
CustomListAction: CustomListView,
}
djadmin_get_action_view_assets(action)¶
Provide CSS/JS assets for views.
Args:
- action - Action instance
Returns: Dict[Type, Dict[str, List[str | JSAsset | CSSAsset]]] - Mapping of action classes to asset dicts
Assets can be specified as plain strings or asset objects (JSAsset/CSSAsset) for advanced features like module loading, deferred loading, or render-blocking behavior.
Example:
@hookimpl
def djadmin_get_action_view_assets(action):
from djadmin import JSAsset, CSSAsset
from djadmin.actions.base import BaseAction
return {
BaseAction: {
'css': ['myfeature/css/theme.css'],
'js': [
# Critical web component JS - loads before rendering to prevent layout shift
JSAsset(src='myfeature/js/webcomponents.js', module=True, blocking=True),
# Non-critical enhancement - deferred loading
JSAsset(src='myfeature/js/feature.js', defer=True),
],
}
}
Script Loading Strategies:
-
blocking=True: Loads in<head>before page renders. Use for critical scripts that must execute before rendering. Trade-off: delays initial render. Note: Does NOT work withmodule=True- ES modules are always deferred by browser specification. -
defer=True: Loads after DOM parsing but before DOMContentLoaded. Best for most application JavaScript that enhances existing elements. -
async_=True: Loads asynchronously without blocking. Use for completely independent scripts like analytics. -
module=True: ES module script (type="module"). Always deferred by browser spec - cannot be made render-blocking even withblocking=True.
Built-in: Theme plugin provides default CSS/JS for all actions.
djadmin_get_action_view_attributes(action)¶
Add attributes to generated view classes.
Args:
- action - Action instance (access to model, model_admin, admin_site)
Returns: Dict[Type, Dict[str, Any]] - Mapping of action classes to attribute dicts
Example:
@hookimpl
def djadmin_get_action_view_attributes(action):
from djadmin.actions.view_mixins import ListActionMixin
return {
ListActionMixin: {
'paginate_by': action.model_admin.paginate_by,
}
}
Built-in: Core plugin provides pagination configuration.
djadmin_get_action_view_attribute_bindings(action)¶
Specify which action attributes should be bound to the view.
Args:
- action - Action instance
Returns: Dict[Type, List[str]] - Mapping of action classes to attribute name lists
Example:
@hookimpl
def djadmin_get_action_view_attribute_bindings(action):
from djadmin.actions.base import BaseAction
return {
BaseAction: ['get_template_names'],
}
Built-in: Core plugin binds methods like get_queryset, get_form_class, etc.
UI Extension Hooks¶
Added in: Milestone 2
These hooks allow plugins to extend the user interface with custom widgets and icons.
djadmin_get_sidebar_widgets(action)¶
Provide sidebar widgets for action views.
Args:
- action - Action instance (for context)
Returns: Dict[Type, List[SidebarWidget]] - Mapping of action classes to widget lists
Example:
@hookimpl
def djadmin_get_sidebar_widgets(action):
from djadmin.dataclasses import SidebarWidget
from djadmin.actions.list_view import ListAction
def get_help_context(view):
return {
'model_name': view.model._meta.verbose_name,
'help_text': view.model_admin.help_text,
}
def has_help_text(view):
return hasattr(view.model_admin, 'help_text')
return {
ListAction: [
SidebarWidget(
template='myapp/help_widget.html',
context_callback=get_help_context,
condition=has_help_text,
order=200, # Display after filters
identifier='help_widget',
)
]
}
SidebarWidget Attributes:
- template (str, required) - Path to widget template
- context_callback (Callable[[view], dict], optional) - Dynamic context provider
- order (int, default: 100) - Display order (lower = first)
- condition (Callable[[view], bool], optional) - Display condition
- identifier (str, optional) - Unique ID for debugging
Built-in: Core plugin provides search widget (order=0).
See also: Sidebar Widgets Guide
djadmin_get_column_header_icons(action)¶
Provide icons for table column headers.
Args:
- action - Action instance (for context)
Returns: Dict[Type, List[ColumnHeaderIcon]] - Mapping of action classes to icon lists
Example:
@hookimpl
def djadmin_get_column_header_icons(action):
from djadmin.dataclasses import ColumnHeaderIcon
from djadmin.actions.list_view import ListAction
def get_icon_template(view, column_name):
# Dynamic icon based on state
if view.is_column_active(column_name):
return 'myapp/icons/active.html'
return 'myapp/icons/inactive.html'
def get_icon_url(view, column_name):
# Generate URL for icon action
return f'{view.request.path}?toggle={column_name}'
def get_icon_title(view, column_name):
return f'Toggle {column_name}'
def should_display(view, column_name):
# Only show for certain columns
return column_name in ['status', 'featured']
return {
ListAction: [
ColumnHeaderIcon(
icon_template=get_icon_template,
url=get_icon_url,
title=get_icon_title,
condition=should_display,
order=50,
identifier='toggle_icon',
)
]
}
ColumnHeaderIcon Attributes:
- icon_template (Callable[[view, column_name], str], required) - Icon template path
- url (Callable[[view, column_name], str], required) - Icon URL
- title (Callable[[view, column_name], str], required) - Tooltip text
- css_class (str, default: '') - CSS classes for icon
- order (int, default: 100) - Display order
- condition (Callable[[view, column_name], bool], optional) - Display condition
- identifier (str, optional) - Unique ID
Built-in: djadmin-filters plugin provides sort icons for orderable columns.
See also: Column Header Icons Guide
Query and Context Hooks¶
djadmin_modify_queryset(queryset, request, view)¶
Modify queryset before rendering.
Args:
- queryset - Original queryset
- request - HTTP request
- view - View instance
Returns: QuerySet - Modified queryset
Example:
@hookimpl
def djadmin_modify_queryset(queryset, request, view):
# Add search filtering
if 'q' in request.GET:
search_term = request.GET['q']
return queryset.filter(title__icontains=search_term)
return queryset
djadmin_add_context_data(context, request, view)¶
Add extra context data to views.
Args:
- context - Current context dict
- request - HTTP request
- view - View instance
Returns: Dict[str, Any] - Additional context data
Example:
@hookimpl
def djadmin_add_context_data(context, request, view):
return {
'feature_enabled': True,
'user_preferences': get_user_prefs(request.user),
}
Built-in: Core plugin adds pagination helpers (page_range, show_first, show_last).
Hook Execution Order¶
Hooks are executed in plugin registration order. The core plugin is always first, followed by other plugins in INSTALLED_APPS order.
For hooks that collect values (like djadmin_get_default_general_actions), all plugin results are aggregated.
Complete Example¶
Here's a plugin using multiple hooks:
# myfeature/djadmin_hooks.py
from djadmin.plugins import hookimpl
@hookimpl
def djadmin_provides_features():
return ['search']
@hookimpl
def djadmin_get_action_view_mixins(action):
from djadmin.actions.view_mixins import ListActionMixin
from .mixins import SearchMixin
return {ListActionMixin: [SearchMixin]}
@hookimpl
def djadmin_get_action_view_assets(action):
from djadmin import JSAsset
from djadmin.actions.view_mixins import ListActionMixin
return {
ListActionMixin: {
'css': ['myfeature/search.css'],
'js': [JSAsset(src='myfeature/search.js', defer=True)],
}
}
@hookimpl
def djadmin_modify_queryset(queryset, request, view):
if 'q' in request.GET:
return queryset.filter(title__icontains=request.GET['q'])
return queryset
@hookimpl
def djadmin_add_context_data(context, request, view):
return {'search_term': request.GET.get('q', '')}
See Also¶
- Creating Plugins - How to build plugins
- Examples - Real-world plugin patterns
- Hook specifications source:
djadmin/plugins/__init__.py