Based on the "Django" category.
Alternatively, view django-treenode alternatives based on common mentions on social networks and blogs.
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of django-treenode or a related project?
Probably the best abstract model / admin for your tree based stuff.
ancestors, children, descendants, parent, root, siblings, tree with no queriestreenode to existing projects| indentation (default) | breadcrumbs | accordion |
|---|---|---|
| treenode-admin-display-mode-indentation | treenode-admin-display-mode-breadcrumbs | treenode-admin-display-mode-accordion |
pip install django-treenodetreenode to settings.INSTALLED_APPStreenode.models.TreeNodeModel (described below)treenode.admin.TreeNodeModelAdmin (described below)python manage.py makemigrations and python manage.py migratemodels.pyMake your model class inherit from treenode.models.TreeNodeModel:
from django.db import models
from treenode.models import TreeNodeModel
class Category(TreeNodeModel):
# the field used to display the model instance
# default value 'pk'
treenode_display_field = "name"
name = models.CharField(max_length=50)
class Meta(TreeNodeModel.Meta):
verbose_name = "Category"
verbose_name_plural = "Categories"
The TreeNodeModel abstract class adds many fields (prefixed with tn_ to prevent direct access) and public methods to your models.
:warning: If you are extending a model that already has some fields, please ensure that your model existing fields names don't clash with TreeNodeModel public methods/properties names.
admin.pyMake your model-admin class inherit from treenode.admin.TreeNodeModelAdmin.
from django.contrib import admin
from treenode.admin import TreeNodeModelAdmin
from treenode.forms import TreeNodeForm
from .models import Category
class CategoryAdmin(TreeNodeModelAdmin):
# set the changelist display mode: 'accordion', 'breadcrumbs' or 'indentation' (default)
# when changelist results are filtered by a querystring,
# 'breadcrumbs' mode will be used (to preserve data display integrity)
treenode_display_mode = TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_ACCORDION
# treenode_display_mode = TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_BREADCRUMBS
# treenode_display_mode = TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_INDENTATION
# use TreeNodeForm to automatically exclude invalid parent choices
form = TreeNodeForm
admin.site.register(Category, CategoryAdmin)
settings.pyYou can use a custom cache backend by adding a treenode entry to settings.CACHES, otherwise the default cache backend will be used.
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
"LOCATION": "...",
},
"treenode": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
},
}
Delete a node if cascade=True (default behaviour), children and descendants will be deleted too,
otherwise children's parent will be set to None (then children become roots):
obj.delete(cascade=True)
Delete the whole tree for the current node class:
cls.delete_tree()
Get a list with all ancestors (ordered from root to parent):
obj.get_ancestors()
# or
obj.ancestors
Get the ancestors count:
obj.get_ancestors_count()
# or
obj.ancestors_count
Get the ancestors pks list:
obj.get_ancestors_pks()
# or
obj.ancestors_pks
Get the ancestors queryset (ordered from parent to root):
obj.get_ancestors_queryset()
Get the breadcrumbs to current node (included):
obj.get_breadcrumbs(attr=None)
# or
obj.breadcrumbs
Get a list containing all children:
obj.get_children()
# or
obj.children
Get the children count:
obj.get_children_count()
# or
obj.children_count
Get the children pks list:
obj.get_children_pks()
# or
obj.children_pks
Get the children queryset:
obj.get_children_queryset()
Get the node depth (how many levels of descendants):
obj.get_depth()
# or
obj.depth
Get a list containing all descendants:
obj.get_descendants()
# or
obj.descendants
Get the descendants count:
obj.get_descendants_count()
# or
obj.descendants_count
Get the descendants pks list:
obj.get_descendants_pks()
# or
obj.descendants_pks
Get the descendants queryset:
obj.get_descendants_queryset()
Get a n-dimensional dict representing the model tree:
obj.get_descendants_tree()
# or
obj.descendants_tree
Get a multiline string representing the model tree:
obj.get_descendants_tree_display()
# or
obj.descendants_tree_display
Get the first child node:
obj.get_first_child()
# or
obj.first_child
Get the node index (index in node.parent.children list):
obj.get_index()
# or
obj.index
Get the last child node:
obj.get_last_child()
# or
obj.last_child
Get the node level (starting from 1):
obj.get_level()
# or
obj.level
Get the order value used for ordering:
obj.get_order()
# or
obj.order
Get the parent node:
obj.get_parent()
# or
obj.parent
Get the parent node pk:
obj.get_parent_pk()
# or
obj.parent_pk
Set the parent node:
obj.set_parent(parent_obj)
Get the node priority:
obj.get_priority()
# or
obj.priority
Set the node priority:
obj.set_priority(100)
Get the root node for the current node:
obj.get_root()
# or
obj.root
Get the root node pk for the current node:
obj.get_root_pk()
# or
obj.root_pk
Get a list with all root nodes:
cls.get_roots()
# or
cls.roots
Get root nodes queryset:
cls.get_roots_queryset()
Get a list with all the siblings:
obj.get_siblings()
# or
obj.siblings
Get the siblings count:
obj.get_siblings_count()
# or
obj.siblings_count
Get the siblings pks list:
obj.get_siblings_pks()
# or
obj.siblings_pks
Get the siblings queryset:
obj.get_siblings_queryset()
Get a n-dimensional dict representing the model tree:
cls.get_tree()
# or
cls.tree
Get a multiline string representing the model tree:
cls.get_tree_display()
# or
cls.tree_display
Return True if the current node is ancestor of target_obj:
obj.is_ancestor_of(target_obj)
Return True if the current node is child of target_obj:
obj.is_child_of(target_obj)
Return True if the current node is descendant of target_obj:
obj.is_descendant_of(target_obj)
Return True if the current node is the first child:
obj.is_first_child()
Return True if the current node is the last child:
obj.is_last_child()
Return True if the current node is leaf (it has not children):
obj.is_leaf()
Return True if the current node is parent of target_obj:
obj.is_parent_of(target_obj)
Return True if the current node is root:
obj.is_root()
Return True if the current node is root of target_obj:
obj.is_root_of(target_obj)
Return True if the current node is sibling of target_obj:
obj.is_sibling_of(target_obj)
Update tree manually, useful after bulk updates:
cls.update_tree()
To perform bulk operations it is recommended to turn off signals, then triggering the tree update at the end:
from treenode.signals import no_signals
with no_signals():
# execute custom bulk operations
pass
# trigger tree update only once
YourModel.update_tree()
# clone repository
git clone https://github.com/fabiocaccamo/django-treenode.git && cd django-treenode
# create virtualenv and activate it
python -m venv venv && . venv/bin/activate
# upgrade pip
python -m pip install --upgrade pip
# install requirements
pip install -r requirements.txt -r requirements-test.txt
# run tests
tox
# or
python setup.py test
# or
python -m django test --settings "tests.settings"
Released under [MIT License](LICENSE.txt).
django-admin-interface - the default admin interface made customizable by the admin itself. popup windows replaced by modals. 🧙 ⚡
django-colorfield - simple color field for models with a nice color-picker in the admin. 🎨
django-extra-settings - config and manage typed extra settings using just the django admin. ⚙️
django-maintenance-mode - shows a 503 error page when maintenance-mode is on. 🚧 🛠️
django-redirects - redirects with full control. ↪️
python-benedict - dict subclass with keylist/keypath support, I/O shortcuts (base64, csv, json, pickle, plist, query-string, toml, xml, yaml) and many utilities. 📘
python-codicefiscale - encode/decode Italian fiscal codes - codifica/decodifica del Codice Fiscale. 🇮🇹 💳
python-fontbro - friendly font operations. 🧢
python-fsutil - file-system utilities for lazy devs. 🧟♂️
*Note that all licence references and agreements mentioned in the django-treenode README section above
are relevant to that project's source code only.
Do not miss the trending, packages, news and articles with our weekly report.