Registry / database / django-tree-queries

django-tree-queries

JSON →
library0.24.0pypypiunverified

django-tree-queries is a Django library that enables efficient querying of hierarchical data structures (trees) using adjacency lists and recursive Common Table Expressions (CTEs). It provides a lightweight solution for managing tree-like models within the Django ORM, focusing on explicit opt-in for tree-specific features rather than extensive configurability. The library is actively maintained, with version 0.24.0 currently available, supporting modern Django and Python versions.

pip install django-tree-queries
INSTALL
IMPORT
SIG · DJANGO-TREE-QUERIE
D
django-tree-queries
databasepythonv0.24.0
Install
1.6s avg
Import
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v0.24.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.000s · 18MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 1.6s · import 0.000s · 19MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

TreeNode
from tree_queries.models import TreeNode
from tree_queries.models import TreeNode

Define a model inheriting from `tree_queries.models.TreeNode`. This automatically adds a `parent` ForeignKey and provides tree-aware query methods. To access `tree_depth`, `tree_path`, and `tree_ordering` fields, you must explicitly call `.with_tree_fields()` on your queryset. Siblings can be ordered using `.order_siblings_by()` method.

import os from django.db import models # Assuming 'myapp' is in INSTALLED_APPS os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') import django django.setup() from tree_queries.models import TreeNode class Category(TreeNode): name = models.CharField(max_length=255) class Meta: app_label = 'myapp' def __str__(self): return self.name # Example Usage (after makemigrations and migrate) # from myapp.models import Category # root = Category.objects.create(name='Electronics') # child1 = Category.objects.create(name='Smartphones', parent=root) # child2 = Category.objects.create(name='Laptops', parent=root) # grandchild = Category.objects.create(name='Gaming Laptops', parent=child2) # Retrieve a tree with additional fields # for node in Category.objects.with_tree_fields().order_siblings_by('name'): # print(f"{'--' * node.tree_depth} {node.name} (depth: {node.tree_depth})")
Debug
Known issues
breakingDjango's standard `order_by()` method is not supported for tree ordering; nodes are returned according to a depth-first search. Use `order_siblings_by("field_name")` instead.
fix
Replace `.order_by(...)` with `.order_siblings_by('field_name')` for sibling ordering. General ordering of the full tree is implicit depth-first.
affects: All versions
gotchaThe `tree_depth`, `tree_path`, and `tree_ordering` fields are only available on querysets where `with_tree_fields()` has been explicitly called. They are not stored in the database or available on newly created/saved instances.
fix
Always append `.with_tree_fields()` to your queryset when you intend to access these tree-specific attributes. Example: `Category.objects.with_tree_fields().get(pk=1)`.
affects: All versions
gotchaPerformance can degrade significantly on very large tables or deep trees, especially when queries involve filtering or aggregating parts of the tree, as the recursive CTE might calculate all trees in the table before filtering.
fix
For very large datasets, consider using `tree_filter()` and `tree_exclude()` for better performance as they filter the base table before building the tree. For complex bottom-up aggregations, consider performing calculations in Python for small trees or exploring other tree libraries (e.g., django-treebeard, django-closuretree) if `django-tree-queries` becomes a bottleneck for specific use cases.
affects: All versions
gotchaThe `parent` foreign key field in models must explicitly be named `parent` for `TreeNode` to function correctly.
fix
Ensure your model's self-referencing ForeignKey is defined as `parent = models.ForeignKey('self', ...)`
affects: All versions
gotchaThe internal representation of `tree_path` and `tree_ordering` can change in future versions and should not be relied upon for application logic, especially for non-PostgreSQL databases where `tree_path` is a string representation.
fix
Use the provided integer `tree_depth` and queryset methods for tree traversal and logic, avoiding direct parsing or reliance on the exact string format of `tree_path` or `tree_ordering` if your application needs to be future-proof or database-agnostic.
affects: All versions
gotchaMySQL and MariaDB databases have a maximum tree depth limit of 50 levels due to their lack of native array support, which `django-tree-queries` uses for `tree_path` and `tree_ordering` internally.
fix
Design your tree structure to stay within the 50-level limit when using MySQL or MariaDB. Consider PostgreSQL for deeper trees.
affects: All versions
Upgrade
Version history
0.24.0latest on PyPI · released Mar 25, 2026
Audit
Dependencies
DjangorequiredCore framework dependency; supports Django 3.2 or better.
psycopg2-binaryoptionalRecommended for PostgreSQL for optimal performance and 'tree_path' array support.
Agent activity
19 hits · last 30 days
node
18
Resources
django-tree-queries — pip install django-tree-queries · libregistry