Working with Admin Classes¶
Using TreeNodeModelAdmin¶
The easiest way to integrate tree structures into Django’s admin panel is by inheriting from TreeNodeModelAdmin. This base class provides all the necessary functionality for managing hierarchical data.
admin.py:¶
from django.contrib import admin
from treenode.admin import TreeNodeModelAdmin
from .models import Category
@admin.register(Category)
class CategoryAdmin(TreeNodeModelAdmin):
# Set the display mode: 'accordion', 'breadcrumbs', or 'indentation'
treenode_display_mode = TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_ACCORDION
# treenode_display_mode = TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_BREADCRUMBS
list_display = ("name",)
search_fields = ("name",)
The changelist renders the full tree on the initial request and expands or collapses nodes on the client without additional AJAX calls. All nodes for the current changelist page are already in the DOM; the accordion only toggles their visibility.
TreeNode uses _path as the canonical tree order in admin responses and queryset traversal, so nodes are rendered in hierarchical order consistently.
You can choose from three display modes:
TREENODE_DISPLAY_MODE_ACCORDION(default) Toggles client-side expand/collapse of already-rendered nodes.TREENODE_DISPLAY_MODE_BREADCRUMBSDisplays the tree as a sequence of breadcrumbs, making it easy to navigate.
The accordion mode is always active, and the setting only affects how nodes are displayed.
Note Earlier versions of this page described lazy-loading of children over AJAX. That is not the shipped behavior: the changelist does not lazy-load tree nodes from the server, so the full page is still bounded by Django's standard changelist pagination. Lazy-loading of tree nodes in the changelist is tracked as a separate feature request.
Search Functionality¶
The search bar helps quickly locate nodes within large trees. As you type, an AJAX request retrieves up to 20 results based on relevance. If you don't find the desired node, keep typing to refine the search until fewer than 20 results remain. The search endpoint is one of the places where the admin does use AJAX; the changelist expand/collapse described above does not.
Working with Forms¶
Using TreeNodeForm¶
If you need to customize forms for tree-based models, inherit from TreeNodeForm. It provides:
- A custom tree widget for selecting parent nodes.
- Automatic exclusion of self and descendants from the parent selection to prevent circular references.
forms.py:¶
from treenode.forms import TreeNodeForm
from .models import Category
class CategoryForm(TreeNodeForm):
"""Form for Category model with hierarchical selection."""
class Meta(TreeNodeForm.Meta):
model = Category
Key Considerations:
- This form automatically ensures that a node cannot be its own parent.
- It uses
TreeWidget, a custom hierarchical dropdown for selecting parent nodes. - If you need a form for another tree-based model, use the dynamic factory method:
CategoryForm = TreeNodeForm.factory(Category)
This method ensures that the form correctly associates with different tree models dynamically.
Using TreeWidget Widget¶
The TreeWidget Class¶
The TreeWidget class is a custom Select2-like widget that enables hierarchical selection in forms.
widgets.py¶
from django import forms
from treenode.widgets import TreeWidget
from .models import Category
class CategorySelectionForm(forms.Form):
parent = forms.ModelChoiceField(
queryset=Category.objects.all(),
widget=TreeWidget(),
required=False
)
Note
- Customizable Data Source: The
data-urlattribute can be adjusted to fetch tree data from a custom endpoint. - Requires jQuery: The widget relies on AJAX requests, so ensure jQuery is available when using it outside Django’s admin.
- Dynamically Fetches Data: It loads the tree structure asynchronously, preventing performance issues with large datasets.
If you plan to use this widget in non-admin templates, make sure the necessary JavaScript and CSS files are included:
<link rel="stylesheet" href="/static/treenode/css/tree_widget.css">
<script src="/static/treenode/js/tree_widget.js"></script>
By following these guidelines, you can seamlessly integrate TreeNodeModelAdmin, TreeNodeForm, and TreeWidget into your Django project, ensuring efficient management of hierarchical data.