django-fast-treenode 2.1.0__py3-none-any.whl → 2.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
treenode/docs/cache.md DELETED
@@ -1,187 +0,0 @@
1
- ## TreeNode Cache Management
2
-
3
- ### First Generation
4
-
5
- The initial caching mechanism was inherited from the `django-treenode` package and was based on the simple use of Django's built-in cache. Each query result was stored in the cache, preventing repeated database queries and thereby improving performance.
6
-
7
- The advantage of this approach was its simplicity: it was easy to integrate and provided a speed boost without complex configurations. However, it also had significant drawbacks. Since the mechanism did not control the total memory usage, it quickly filled the cache with a vast number of small queries. This led to cache system overload, reduced efficiency, and slowed down other parts of the application that relied on the same cache. As a result, intensive operations with tree structures could cause memory management issues and impact cache system performance.
8
-
9
- ---
10
-
11
- ### Second Generation
12
-
13
- In the current version, the caching mechanism has been enhanced with **memory usage limitation** for all models inheriting from `TreeNodeModel`. This was implemented as a **FIFO queue (First In, First Out)**, which automatically removes the oldest entries when the limit is exceeded.
14
-
15
- The choice of FIFO was driven by the package's universality. `django-fast-treenode` is designed to work in various scenarios, so it needed a strategy that efficiently handles evenly distributed queries. Even if queries are not evenly distributed in a particular project (e.g., some nodes are accessed more frequently than others), FIFO does not significantly reduce cache performance compared to the first-generation approach. However, it prevents uncontrolled memory growth, ensuring stable cache operation even under high request loads.
16
-
17
-
18
- #### Key Features
19
-
20
- **Global Cache Limit**: The setting `TREENODE_CACHE_LIMIT` defines the maximum cache size (in MB) for **all models** inheriting from `TreeNodeModel`. Default is **100MB** if not explicitly set in `settings.py`.
21
-
22
- **settings.py**
23
- ``` python
24
- TREENODE_CACHE_LIMIT = 100
25
- ```
26
-
27
- **Automatic Management**. In most cases, users don’t need to manually manage cache operations.All methods that somehow change the state of models reset the tree cache automatically.
28
-
29
- **Manual Cache Clearing**. If for some reason you need to reset the cache, you can do it in two ways:
30
- - **Clear cache for a single model**: Use `clear_cache()` at the model level:
31
- ```python
32
- MyTreeNodeModel.clear_cache()
33
- ```
34
- - **Clear cache for all models**: Use the global `treenode_cache.clear()` method:
35
- ```python
36
- from treenode.cache import treenode_cache
37
- treenode_cache.clear()
38
- ```
39
-
40
- ---
41
-
42
- ### Ceche API
43
-
44
- #### `@cached_method` Decorator
45
-
46
- The `@cached_method` decorator is available for caching method results in **class and instance methods** of models inheriting from `TreeNodeModel`. This decorator helps optimize performance by reducing redundant computations.
47
-
48
- ```python
49
- from treenode.cache import cached_method
50
- from treenode.models import TreeNodeModel
51
-
52
- class Category(TreeNodeModel):
53
- name = models.CharField(max_length=50)
54
-
55
- @cached_method
56
- def my_tree_method(self):
57
- # Your code is here
58
- ```
59
-
60
- In this example, `my_tree_method()` is cached.
61
-
62
- **Important:** The decorator should **only** be used with `TreeNodeModel` subclasses. Applying it to other classes will cause unexpected behavior.
63
-
64
-
65
- #### Accessing Cache via `treenode_cache`
66
-
67
- A global cache instance `treenode_cache` provides direct cache manipulation methods, allowing you to generate cache keys, store, retrieve, and invalidate cached values.
68
-
69
- Methods available in `treenode_cache`:
70
-
71
- #### generate_cache_key()
72
- Generates a unique cache key for caching method results. The key is based on model name, method name, object identifier, and method parameters.
73
-
74
- ```python
75
- cache_key = treenode_cache.generate_cache_key(
76
- label=Category._meta.label, # Model label
77
- func_name=self.<The method you are in>.__name__,
78
- unique_id=42, # This can be the object.pk. In a desperate situation, use id(self)
79
- attr="some string value"
80
- )
81
- ```
82
- This ensures that the cache key follows Django's conventions and remains unique.
83
-
84
- #### set()
85
- Stores a value in the cache.
86
-
87
- ```python
88
- treenode_cache.set(cache_key, {'name': 'Root', 'id': 1})
89
- ```
90
- This caches a dictionary object under the generated key.
91
-
92
- #### get()
93
- Retrieves a cached value by its cache key.
94
-
95
- ```python
96
- cached_value = treenode_cache.get(cache_key)
97
- if cached_value is None:
98
- cached_value = compute_expensive_query()
99
- treenode_cache.set(cache_key, cached_value)
100
- ```
101
-
102
- #### invalidate()
103
- Removes all cached entries for a **specific model**.
104
-
105
- ```python
106
- treenode_cache.invalidate(Category._meta.label)
107
- ```
108
- This clears all cache entries related to `Category` instances.
109
-
110
- #### clear()
111
- Clears **all** cached entries in the system.
112
-
113
- ```python
114
- treenode_cache.clear()
115
- ```
116
- This completely resets the cache, removing **all stored values**.
117
-
118
- Best Practices:
119
- - **Always use `generate_cache_key()`** instead of hardcoding cache keys to ensure consistency.
120
- - **Use `invalidate()` instead of `clear()`** when targeting a specific model’s cache.
121
- - **Apply `@cached_method` wisely**, ensuring it is used **only for** `TreeNodeModel`-based methods to avoid conflicts.
122
- - **Be mindful of cache size**, as excessive caching can lead to memory bloat.
123
-
124
- By leveraging these caching utilities, `django-fast-treenode` ensures efficient handling of hierarchical data while maintaining high performance.
125
-
126
- ---
127
-
128
- ### Third Generation (Currently in Development)
129
-
130
- The next version of the caching mechanism introduces adaptability, a **split between "cold" and "hot" caches**, and enhanced eviction strategies. Key improvements include:
131
-
132
- #### 1. Two-Tier Caching System
133
-
134
- The cache is now divided into two queues:
135
-
136
- - **FIFO (70%-80%)** – for new and infrequently accessed data.
137
- - **LRU (20%-30%)** – for frequently accessed objects (Least Recently Used).
138
-
139
- How it works:
140
- - If tree queries are evenly distributed, the cache behaves like a standard FIFO.
141
- - If certain nodes receive frequent queries, those records automatically move to LRU, reducing database load.
142
-
143
- #### 2. Moving Data Between FIFO and LRU
144
-
145
- Each new entry initially goes into **FIFO**. If accessed **more than N times**, it moves to **LRU**, where it remains longer.
146
-
147
- **How N is determined:**
148
- - A threshold is set based on **mathematical statistics**: N = 1 / sqrt(2).
149
- - An absolute threshold limit is added.
150
-
151
- **LRU Behavior:**
152
- - When accessed, a record moves to the top of the list.
153
- - New records are also placed at the top.
154
- - If LRU reaches capacity, **the evicted record returns to FIFO** instead of being deleted.
155
-
156
- #### 3. Cache Invalidation
157
-
158
- When data is modified or deleted, the cache **automatically resets** to prevent outdated information. This ensures that modified tree structures do not retain stale data in the cache.
159
-
160
- #### 4. Dynamic Time Threshold (DTT)
161
-
162
- To automatically clear outdated records, an **adaptive mechanism** is used. Instead of a static TTL, the **DTT parameter** is dynamically calculated based on **Poisson distribution**.
163
-
164
- How DTT is calculated:
165
- 1. Compute the **average interval between queries (T)**: ``` T = (1/N) * Σ (t_i - t_(i-1)), i=1...N```
166
- 2. Store **averaged value** `ΣΔt / N`
167
- 3. Set **DTT = 3T**, which removes **95% of infrequent queries**.
168
-
169
- **Why this is better than a fixed TTL:**
170
- - If queries are rare → DTT **increases**, preventing premature deletions.
171
- - If queries are frequent → DTT **decreases**, accelerating cache clearing.
172
-
173
- All calculations happen **automatically**, without manual configuration.
174
-
175
- Additionally, this mechanism will support synchronization in multiprocess environments (WSGI, Gunicorn, Uvicorn).
176
-
177
- ---
178
-
179
- ### Fourth Generation (Planned)
180
-
181
- The next generation of caching will include:
182
-
183
- - **Middleware for caching nodes**, considering nested objects.
184
- - **"Smart" prediction** of peak and dynamics of loads.
185
- - **Asynchronous operations** support, ensuring efficient caching and retrieval in non-blocking environments.
186
-
187
- Future versions will continue improving this mechanism, making it **even more efficient and predictable** when working with large tree structures.
@@ -1,35 +0,0 @@
1
- ## Import&Export Functionality
2
- ### Overview
3
-
4
- TreeNode v2.0 includes **built-in export and import features** for easier data migration. Supported Formats: `csv`, `json`, `xlsx`, `yaml`, `tsv`. The system supports importing and exporting data for any models, allowing users to efficiently manage and update data while preserving its structure and relationships.
5
-
6
- ### Installation for Import/Export Features
7
- By default, import/export functionality is **not included** to keep the package lightweight. If you need these features, install the package with:
8
- ```bash
9
- pip install django-fast-treenode[import_export]
10
- ```
11
-
12
- Once installed, **import/export buttons will appear** in the Django admin interface.
13
-
14
- ### Data Processing Logic
15
- When importing data into the system, **three key fields** must be present:
16
- - **`id`** – the unique identifier of the record.
17
- - **`tn_parent`** – the identifier of the parent node.
18
- - **`tn_priority`** – the ordinal number of the node among its parent's children.
19
-
20
- These fields ensure the correct construction of the hierarchical data structure.
21
-
22
- Important:
23
- - If a record with the same `id` **already exists** in the database, its data **will be updated** with the imported values.
24
- - If no record with the given `id` **is found**, a **new record will be created** with the specified parameters.
25
-
26
- This import mechanism is designed to allow users to:
27
- - **Export data**, edit it (e.g., in a CSV, Excel, or JSON file).
28
- - **Upload the modified file** without disrupting the model structure.
29
- - **Update only the changed data**, keeping relationships with other models intact (e.g., without altering primary and foreign key values).
30
-
31
- This approach provides **flexible data management**, enabling users to safely apply modifications without manually updating each record in the system.
32
-
33
- ### Important Considerations
34
-
35
- Exporting objects with M2M fields may lead to serialization issues. Some formats (e.g., CSV) do not natively support many-to-many relationships. If you encounter errors, consider exporting data in `json` or `yaml` format, which better handle nested structures.
treenode/docs/index.md DELETED
@@ -1,30 +0,0 @@
1
- # Django Fast TreeNode
2
-
3
- Welcome to the **django-fast-treenode** documentation!
4
-
5
- ## Key Features
6
- **django-fast-treenode** is a high-performance solution for managing tree structures in Django.
7
-
8
- - **Fast processing** even with deep trees
9
- - **Intuitive API** for seamless integration
10
- - **Django Admin support** for easy management
11
- - **Optimized caching** for enhanced performance
12
-
13
- ## Contents
14
- - [About the Project](about.md)
15
- - [Installation, Configuration, and Fine-Tuning](installation.md)
16
- - [Model Inheritance and Extensions](models.md)
17
- - [Working with Admin Classes](admin.md)
18
- - [API Reference](api.md)
19
- - [Import & Export](import_export.md)
20
- - [Caching and Cache Management](cache.md)
21
- - [Migration and Upgrade Guide](migration.md)
22
- - [Roadmap](roadmap.md)
23
-
24
- ## Links
25
- - [Issues](https://github.com/TimurKady/django-fast-treenode/issues)
26
- - [Pull Requests](https://github.com/TimurKady/django-fast-treenode/pulls)
27
- - [Discussions](https://github.com/TimurKady/django-fast-treenode/discussions)
28
-
29
- ## License
30
- Released under the [MIT License](https://github.com/TimurKady/django-fast-treenode/blob/main/LICENSE).
@@ -1,74 +0,0 @@
1
- ## Configuration Guide
2
-
3
- ### Installation
4
-
5
- #### First-Time Installation
6
- If you are installing `django-fast-treenode` for the first time, the process is straightforward. Simply install the package via `pip`:
7
-
8
- ```sh
9
- pip install django-fast-treenode
10
- ```
11
-
12
- Once installed, add `'treenode'` to your `INSTALLED_APPS` in `settings.py`:
13
- ##### settings.py
14
- ```python
15
- INSTALLED_APPS = [
16
- ...
17
- 'treenode',
18
- ]
19
- ```
20
-
21
- Then, apply migrations:
22
-
23
- ```sh
24
- python manage.py migrate
25
- ```
26
-
27
- #### Upgrading or Migrating from `django-treenode`
28
- If you are upgrading to a new version of `django-fast-treenode` or switching from `django-treenode`, it is essential to run migrations to ensure data consistency:
29
-
30
- ```sh
31
- pip install --upgrade django-fast-treenode
32
- python manage.py migrate
33
- ```
34
-
35
- #### Migrating from Other Packages
36
- If you are migrating from other tree management solutions, additional steps may be required. Please refer to the [Migration and Upgrade Guide](migration.md) for detailed instructions.
37
-
38
- ---
39
-
40
- ### Configuration
41
-
42
- #### Cache Setup
43
- To optimize performance, `django-fast-treenode` uses caching for tree structure operations. You can define a **dedicated cache backend** for the package by adding a `"treenode"` entry to `settings.CACHES`. If no dedicated cache is provided, the default Django cache will be used.
44
-
45
- ##### settings.py
46
- ```python
47
- CACHES = {
48
- "default": {
49
- "BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
50
- "LOCATION": "...",
51
- },
52
- "treenode": {
53
- "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
54
- "KEY_PREFIX": "", # This is important!
55
- "VERSION": None, # This is important!
56
- },
57
- }
58
- ```
59
- **Important Notes:**
60
- - You can use **any cache backend**, including Django’s built-in options or external solutions like **Redis** or **Memcached** .
61
- - **`KEY_PREFIX` must be an empty string (`""`)**, and **`VERSION` must be `None`**, otherwise cache inconsistencies may occur.
62
-
63
- ---
64
-
65
- #### Cache Size Allocation
66
- By default, the cache stores all tree-related data for models inheriting from `TreeNodeModel`. You can control the cache size using `TREENODE_CACHE_LIMIT` in **megabytes**.
67
-
68
- ##### settings.py
69
- ```python
70
- TREENODE_CACHE_LIMIT = 100
71
- ```
72
- This setting determines the memory allocation for caching **all instances** of tree models.
73
-
74
- For more details on how caching works and how to fine-tune its behavior, refer to the [Caching and Cache Management](cache.md) Guide.
@@ -1,145 +0,0 @@
1
- ## Migrations Guide
2
- ### Migration from _django-treenode_ packege
3
- The migration process from `django-treenode` is fully automated. No manual steps are required. Upon upgrading, the necessary data structures will be checked and updated automatically.
4
- Run the following commands in the terminal:
5
-
6
- ```bash
7
- pip install django-fast-treenode
8
- python manage.py makemigrations
9
- python manage.py migrate
10
- python manage.py runserver
11
- ```
12
- It's unlikely that you'll need or want this, but in exceptional cases you can call the whole tree update code `cls.update_tree()` manually.
13
-
14
- ---
15
-
16
- ### Update _django-fast-treenode_ version 2.1 and less
17
- The sequence of actions when migrating from previous versions of `django-fast-treenode` is similar to upgrading models of the `django-treenode` package.
18
- Run the following commands in the terminal:
19
-
20
- ```bash
21
- pip install --upgrade django-fast-treenode
22
- python manage.py makemigrations
23
- python manage.py migrate
24
- python manage.py runserver
25
- ```
26
- Now your models are updated and running even faster than before.
27
-
28
- ---
29
-
30
- ### Migration from _django-mptt_ or _django-treebeard_ packege
31
- Migration from other packages is not as seamless as with `django-treebeard`, which is probably understandable. However, `django-fast-treenode` has been specially tweaked so that such migration requires minimal effort, including minimal changes to your project code.
32
- Below is a guide on how to migrate to `django-fast-treenode` from other packages using a project using `django-treebeard` as an example. Migration from other packages will involve similar steps.
33
-
34
- #### Step 1: Export existing data
35
- Launch the Python console:
36
-
37
- ```bash
38
- python manage.py shell
39
- ```
40
-
41
- Run the following code to export the tree structure:
42
- ```python
43
- from yourapp.models import Category
44
- import json
45
-
46
- data = []
47
-
48
- def export_tree(node):
49
- children = node.get_children()
50
- return {
51
- "id": node.id,
52
- "tn_parent": node.get_parent().id if node.get_parent() else None,
53
- "name": node.name,
54
- # Continue the list by inserting the required model fields
55
- # Do not export the `children` field
56
- }
57
-
58
- roots = Category.objects.filter(depth=1) # treebeard root nodes
59
- for root in roots:
60
- data.append(export_tree(root))
61
-
62
- with open("tree_data.json", "w") as f:
63
- json.dump(data, f, indent=4)
64
- ```
65
-
66
- This code exports your structure to `tree_data.json` file. JSON preserves the id → tn_parent relationship, but without children.
67
-
68
- Now clear the table:
69
- ```python
70
- Category.objects.all().delete()
71
- ```
72
- Remove `django-treebeard` if it is installed:
73
- ```bash
74
- pip uninstall django-treebeard
75
- ```
76
- Install `django-fast-treenode`:
77
- ```bash
78
- pip install django-fast-treenode
79
- ```
80
-
81
- Before you start the migration, it is important to make sure **you have a backup of your database**, as the tree storage structure will change.
82
-
83
- #### Step 2: Preparing for Migration
84
- If you have a model in your project that uses `treebeard`, it probably looks like this:
85
- ```python
86
- from treebeard.mp_tree import MP_Node
87
-
88
- class Category(MP_Node):
89
- name = models.CharField(max_length=255)
90
- ```
91
- Now we need to adapt it for `django-fast-treenode`. Change the model to use `TreeNodeModel` instead of `MP_Node`:
92
- ```python
93
- from treenode.models import TreeNodeModel
94
-
95
- class Category(TreeNodeModel):
96
- name = models.CharField(max_length=255)
97
-
98
- treenode_display_field = "name"
99
- treenode_sort_field = "None"
100
- ```
101
- Be sure to add `treenode_display_field` as `django-fast-treenode` uses it to display nodes in the admin panel.
102
-
103
- The `treenode_sort_field` attribute specifies the tree sorting order. The default value of this field is `None`. It will sort by the internal field `tn_priority`.
104
-
105
- The `tn_priority` value will be generated automatically if not specified during import. It will either be set as nodes are inserted into the tree (in the order in which the nodes will appear in the imported data), or after they are inserted, depending on the results of sorting by the field specified in the `treenode_sort_field` attribute.
106
-
107
- > Note: sorting functions are available for `django-tree-node` version 2.3 and higher.
108
-
109
- #### Step 3: Update the code
110
- The `django-fast-treenode` package contains the full set of methods you are used to. But the methods for working with the tree are slightly different. For example:
111
-
112
- |**django-treebeard** | **django-fast-treenode** |**Features of use**|
113
- |---------------------|----------------------|----------------------|
114
- | The `pos` parameter in `add_sibling()` and `move()` methods | The parameter `pos` has the name `position` | • The `position` parameter in `django-fast-treenode` always consists of two parts separated by `-`: the first part determines the insertion method (_first, left, right, last, sorted_), the second — the placement type (_child, sibling_). <br> • Instead of a string format, you can also pass position as an integer indicating the exact position of the node in the list.|
115
- |`get_siblings()`, `get_ancestors()` end ect. | Similar methods have parameters `include_self` and `depth` |• The `include_self` parameter specifies whether to include the node itself in the selection. <br> • The `depth` parameter specifies the depth of the search. |
116
- |`move(target, pos)` metiod| The method `move()` has the name `move_to(target, position)` | - |
117
-
118
- As you can see, unlike treebeard, django-fast-treenode provides more features, allowing you to use familiar methods more flexibly.
119
-
120
- For more details, refer to the `django-fast-treenode` documentation and update your code accordingly
121
-
122
-
123
- #### Step 4: Create Migrations
124
- After changing the model, new migrations need to be created and applied.
125
-
126
- ```bash
127
- python manage.py makemigrations
128
- python manage.py migrate
129
- ```
130
-
131
- After a successful migration, you can remove references to `django-treebeard` in `requirements.txt` and `INSTALLED_APPS` if they were there.
132
-
133
- #### Step 5: Data Import
134
- Now start the server.
135
- ```bash
136
- python manage.py runserver
137
- ```
138
-
139
- Go to Django Admin and import data into your model from the previously saved file. `django-fast-treenode` will do everything automatically. Check if the tree structure is displayed correctly.
140
-
141
- Moreover, the import will preserve the `id` of all nodes, which will ensure that the values of the keys referencing your model are unchanged.
142
-
143
- ---
144
-
145
- Now your project has completely migrated from `django-treebeard` to `django-fast-treenode`. Your tree is more performant and easier to use, and your code is cleaner and more flexible.
treenode/docs/models.md DELETED
@@ -1,128 +0,0 @@
1
- ## Model Inheritance and Extensions
2
-
3
- ### Model Inheritance
4
-
5
- To define a model that supports tree structures, simply inherit from `TreeNodeModel`. Below is an example of a basic category model:
6
-
7
- ##### models.py
8
-
9
- ```python
10
- from django.db import models
11
- from treenode.models import TreeNodeModel
12
-
13
- class Category(TreeNodeModel):
14
-
15
- treenode_display_field = "name" # Defines the field used for display in the admin panel
16
-
17
- name = models.CharField(max_length=50)
18
-
19
- class Meta(TreeNodeModel.Meta): # Ensure TreeNodeModel's indexing settings are preserved
20
- verbose_name = "Category"
21
- verbose_name_plural = "Categories"
22
- ```
23
-
24
- Key Considerations:
25
- - `treenode_display_field`
26
- This attribute defines which field will be used to display the tree structure in the Django admin panel. If it is not set, nodes will be named generically as `"Node <id>"`, where `<id>` is the primary key of the record.
27
- - Inheriting model Meta class from `TreeNodeModel.Meta`
28
- It is **essential** to inherit the `Meta` class from `TreeNodeModel.Meta`. Failure to do so may impact database performance and query efficiency.
29
-
30
- With this setup, your model will seamlessly integrate into Django, supporting hierarchical relationships while maintaining optimized indexing and efficient querying.
31
-
32
-
33
- ### Model Extending
34
-
35
- When extending a model based on `TreeNodeModel`, you have full flexibility to add custom fields and methods. However, to ensure compatibility and maintainability, follow these best practices.
36
-
37
- #### General Guidelines
38
- You are free to add new fields and methods. The basic model does not impose any restrictions on the expansion of functionality. However, it is strongly recommended to adhere to the principles and standards of the object-oriented approach.
39
- **Avoid direct access to model fields** when modifying tree-related data.
40
- Fields with the `tn_` prefix **may be renamed in future versions** (this is already planned). Instead of assigning values directly, use **accessor and mutator methods**:
41
- ```python
42
- # ❌ Avoid direct assignment
43
- node.tn_parent = other_node
44
-
45
- # ✅ Use the provided method
46
- node.set_parent(other_node)
47
- ```
48
- **Hardcoding field names may lead to compatibility issues in future updates.** Always use methods provided by the package when working with tree structures.
49
-
50
- #### Extending Indexing
51
-
52
- If your model requires additional indexing, **do not override the indexing settings of `TreeNodeModel.Meta`**. Instead, extend them properly using Django’s index definitions.
53
-
54
- If you want to add an index to a new or existing field (e.g., `"name"`), do it as follows:
55
-
56
- ```python
57
- from django.db import models
58
- from treenode.models import TreeNodeModel
59
-
60
- class Category(TreeNodeModel):
61
-
62
- treenode_display_field = "name"
63
-
64
- name = models.CharField(max_length=50, db_index=True) # Adding an index to "name"
65
-
66
- class Meta(TreeNodeModel.Meta): # Preserve indexing settings from TreeNodeModel
67
- indexes = TreeNodeModel.Meta.indexes + [
68
- models.Index(fields=["name"]),
69
- ]
70
- verbose_name = "Category"
71
- verbose_name_plural = "Categories"
72
- ```
73
-
74
- By following these principles, your extended models will remain stable, maintainable, and compatible with future versions of `django-fast-treenode`.
75
-
76
- ### Customize Managers
77
-
78
- When defining custom model managers for `TreeNodeModel`, it is **essential** to extend `TreeNodeModelManager` rather than modifying internal components like `ClosureQuerySet`, `ClosureModelManager`, or `TreeNodeQuerySet`. Direct manipulation of these lower-level structures **can lead to data corruption** and is not guaranteed to remain stable in future versions.
79
-
80
- #### Always Extend TreeNodeModelManager
81
- To ensure stability and maintain tree integrity, always **extend** `TreeNodeModelManager`. Never directly interact with internal tree structures like the Closure Table or adjacency list.
82
-
83
- Example: Safe Custom Manager:
84
- ```python
85
- from treenode.managers import TreeNodeModelManager
86
-
87
- class CustomTreeNodeManager(TreeNodeModelManager):
88
- def active(self):
89
- """Return only active nodes."""
90
- return self.get_queryset().filter(is_active=True)
91
- ```
92
- **Correct**: This approach preserves all core tree operations while adding custom behavior.
93
-
94
- #### Avoid Direct Parent-Child Modifications
95
- Modifying relationships improperly can break the tree structure. Use built-in methods instead:
96
-
97
- Safe Parent Update:
98
- ```python
99
- node.set_parent(new_parent) # ✅ Safe
100
- node.tn_parent = new_parent # ❌ Unsafe (bypasses tree updates)
101
- ```
102
-
103
- #### **3. Use `bulk_create` and `bulk_update` Carefully**
104
- Since tree structures require synchronization between adjacency and closure models, **always use transactions**:
105
-
106
- Safe Bulk Create Example:
107
-
108
- ```python
109
- from django.db import transaction
110
-
111
- class CustomTreeNodeManager(TreeNodeModelManager):
112
- @transaction.atomic
113
- def bulk_create(self, objs, batch_size=1000):
114
- """Ensures proper insertion of nodes without breaking the tree."""
115
- objs = super().bulk_create(objs, batch_size=batch_size)
116
- return objs
117
- ```
118
- **Important**: Do not directly insert nodes without using `bulk_create` from `TreeNodeModelManager`.
119
-
120
- #### Custom Queries
121
- Use `get_queryset()` Instead of QuerySet Overrides. If custom queries are needed, **override `get_queryset()`** in your manager instead of modifying internal querysets:
122
- ```python
123
- class CustomTreeNodeManager(TreeNodeModelManager):
124
- def get_queryset(self):
125
- return super().get_queryset().filter(is_active=True)
126
- ```
127
-
128
- By following these principles, you ensure your custom managers remain **future-proof**, **safe**, and **maintainable** without the risk of breaking tree integrity.
treenode/docs/roadmap.md DELETED
@@ -1,45 +0,0 @@
1
- ## Roadmap
2
- The latest version provides optimized database operations, an improved caching mechanism, and enhanced integration capabilities, making it a **robust and efficient choice** for handling tree structures.
3
-
4
- But the **django-fast-treenode** package will continue to evolve from its original concept—combining the benefits of the **Adjacency List** and **Closure Table** models—into a high-performance solution for managing and visualizing hierarchical data in Django projects. The focus is on **speed, usability, and flexibility**.
5
-
6
- In future versions, I plan to implement:
7
-
8
- ### **Version 2.1 – Compatibility and Optimization**
9
- Reducing dependencies and simplifying migration from other libraries.
10
- - **Expanding functionality** to simplify migration from other tree packages.
11
- - Introducing node **filtering and search with AJAX**.
12
- - **Optimizing query performance** by reducing query complexity and improving indexing strategies.
13
- - **Reducing database load** from the `TreeNodeAdmin` when working with large trees.
14
- - Removing `numpy` in favor of lighter alternatives.
15
-
16
- ### **Version 2.2 – Caching Improvements**
17
- Speeding up tree operations and reducing database load.
18
- - **Implementing a more efficient caching algorithm** to optimize performance and reduce recomputation.
19
- - **Refining cache expiration strategies** for better memory management.
20
-
21
- ### **Version 2.3 – Performance Enhancements**
22
- - **Reducing query overhead** and optimizing bulk operations for large datasets.
23
- - **Django REST Framework (DRF)**: Adding initial integration for efficient tree-based API handling.
24
- - **Serialization**: Developing lightweight tree serialization for API-first projects.
25
- - **Enhancing node filtering and search** with AJAX-driven interfaces.
26
-
27
- ### **Version 2.4 – Drag-and-Drop and Admin UI Improvements**
28
- - **Drag-and-Drop**: Adding drag-and-drop support for node sorting in Django admin.
29
- - **Advanced Sorting**: Adding multiple sorting strategies for tree nodes, including manual ordering and hierarchical priority rules.
30
- - **Admin Panel Enhancements**: Expanding the functionality of the Django admin interface for managing hierarchical data more efficiently.
31
-
32
- ### **Version 3.0 – Asynchronous operations and Fourth-Generation Cache Management System**
33
- - **Asynchronous operations** support, ensuring efficient working and data processing in non-blocking environments.
34
- - **Shifting from caching computed results to directly caching tree nodes**, reducing recomputation overhead and improving cache efficiency.
35
- - **Reworking Adjacency List and Closure Table managers** for a new caching system.
36
- - **Enhancing cache consistency** across multiple processes (WSGI, Gunicorn, Uvicorn) with a global synchronization mechanism.
37
-
38
- ### **Version 4.0 – Moving Beyond Django ORM**
39
- Enabling tree structures to function without a strict dependency on Django ORM while maintaining compatibility.
40
- - **Introducing support for various storage backends**, allowing greater flexibility.
41
- - **Adding compatibility with Redis for in-memory tree storage** and JSON-based trees for lightweight embedded storage.
42
- - **Expanding usage in API-first projects**, enabling tree structures to work independently from Django models.
43
-
44
- Stay tuned for updates!
45
- Your wishes, objections, and comments are welcome.