django-fast-treenode 1.1.3__py3-none-any.whl → 2.0.1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.1.dist-info}/METADATA +127 -46
- django_fast_treenode-2.0.1.dist-info/RECORD +41 -0
- {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.1.dist-info}/WHEEL +1 -1
- treenode/__init__.py +0 -7
- treenode/admin.py +327 -82
- treenode/apps.py +20 -3
- treenode/cache.py +231 -0
- treenode/docs/Documentation +101 -54
- treenode/forms.py +75 -19
- treenode/managers.py +260 -48
- treenode/models/__init__.py +7 -0
- treenode/models/classproperty.py +24 -0
- treenode/models/closure.py +168 -0
- treenode/models/factory.py +71 -0
- treenode/models/proxy.py +650 -0
- treenode/static/treenode/css/tree_widget.css +62 -0
- treenode/static/treenode/css/treenode_admin.css +106 -0
- treenode/static/treenode/js/tree_widget.js +161 -0
- treenode/static/treenode/js/treenode_admin.js +171 -0
- treenode/templates/admin/export_success.html +26 -0
- treenode/templates/admin/tree_node_changelist.html +11 -0
- treenode/templates/admin/tree_node_export.html +27 -0
- treenode/templates/admin/tree_node_import.html +27 -0
- treenode/templates/widgets/tree_widget.css +23 -0
- treenode/templates/widgets/tree_widget.html +21 -0
- treenode/urls.py +34 -0
- treenode/utils/__init__.py +4 -0
- treenode/utils/base36.py +35 -0
- treenode/utils/exporter.py +141 -0
- treenode/utils/importer.py +296 -0
- treenode/version.py +11 -1
- treenode/views.py +102 -2
- treenode/widgets.py +49 -27
- django_fast_treenode-1.1.3.dist-info/RECORD +0 -33
- treenode/compat.py +0 -8
- treenode/factory.py +0 -68
- treenode/models.py +0 -668
- treenode/static/select2tree/.gitkeep +0 -1
- treenode/static/select2tree/select2tree.css +0 -176
- treenode/static/select2tree/select2tree.js +0 -181
- treenode/static/treenode/css/treenode.css +0 -85
- treenode/static/treenode/js/treenode.js +0 -201
- treenode/templates/widgets/.gitkeep +0 -1
- treenode/templates/widgets/attrs.html +0 -7
- treenode/templates/widgets/options.html +0 -1
- treenode/templates/widgets/select2tree.html +0 -22
- treenode/tests.py +0 -3
- {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.1.dist-info}/LICENSE +0 -0
- {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.1.dist-info}/top_level.txt +0 -0
- /treenode/{docs → templates/admin}/.gitkeep +0 -0
@@ -1,28 +1,44 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: django-fast-treenode
|
3
|
-
Version:
|
3
|
+
Version: 2.0.1
|
4
4
|
Summary: Application for supporting tree (hierarchical) data structure in Django projects
|
5
5
|
Home-page: https://github.com/TimurKady/fast-treenode
|
6
6
|
Author: Timur Kady
|
7
|
-
Author-email: timurkady@yandex.com
|
8
|
-
License: MIT
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
7
|
+
Author-email: Timur Kady <timurkady@yandex.com>
|
8
|
+
License: MIT License
|
9
|
+
|
10
|
+
Copyright (c) 2020-2023 Timur Kady
|
11
|
+
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
14
|
+
in the Software without restriction, including without limitation the rights
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
17
|
+
furnished to do so, subject to the following conditions:
|
18
|
+
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
20
|
+
copies or substantial portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
28
|
+
SOFTWARE.
|
29
|
+
Project-URL: Homepage, https://github.com/TimurKady/django-fast-treenode
|
30
|
+
Project-URL: Documentation, https://github.com/TimurKady/django-fast-treenode#readme
|
31
|
+
Project-URL: Source, https://github.com/TimurKady/django-fast-treenode
|
32
|
+
Project-URL: Issues, https://github.com/TimurKady/django-fast-treenode/issues
|
33
|
+
Requires-Python: >=3.9
|
23
34
|
Description-Content-Type: text/markdown
|
24
35
|
License-File: LICENSE
|
25
|
-
Requires-Dist: Django
|
36
|
+
Requires-Dist: Django>=4.0
|
37
|
+
Requires-Dist: pympler>=1.0
|
38
|
+
Provides-Extra: import-export
|
39
|
+
Requires-Dist: openpyxl; extra == "import-export"
|
40
|
+
Requires-Dist: pyyaml; extra == "import-export"
|
41
|
+
Requires-Dist: pandas; extra == "import-export"
|
26
42
|
|
27
43
|
# Django-fast-treenode
|
28
44
|
__Combination of Adjacency List and Closure Table__
|
@@ -76,8 +92,7 @@ You can easily find additional information on your own on the Internet.
|
|
76
92
|
4. Make your model-admin inherit from ```treenode.admin.TreeNodeModelAdmin``` (described below)
|
77
93
|
5. Run python manage.py makemigrations and ```python manage.py migrate```
|
78
94
|
|
79
|
-
|
80
|
-
It will automatically build a new and complete Closure Table for your tree.
|
95
|
+
For more information on migrating from the **django-treenode** package and upgrading to version 2.0, see [below](#migration-guide).
|
81
96
|
|
82
97
|
## Configuration
|
83
98
|
### `models.py`
|
@@ -143,6 +158,8 @@ CACHES = {
|
|
143
158
|
},
|
144
159
|
"treenode": {
|
145
160
|
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
|
161
|
+
"KEY_PREFIX": "", # This is important!
|
162
|
+
"VERSION": None, # This is important!
|
146
163
|
},
|
147
164
|
}
|
148
165
|
```
|
@@ -150,15 +167,11 @@ CACHES = {
|
|
150
167
|
|
151
168
|
```
|
152
169
|
class YoursForm(TreeNodeForm):
|
153
|
-
|
154
|
-
class Meta:
|
155
|
-
widgets = {
|
156
|
-
'tn_parent': TreeWidget(attrs={'style': 'min-width:400px'}),
|
157
|
-
}
|
170
|
+
# Your code is here
|
158
171
|
```
|
159
172
|
|
160
|
-
## Usage
|
161
173
|
|
174
|
+
## Usage
|
162
175
|
### Methods/Properties
|
163
176
|
|
164
177
|
- [`delete`](#delete)
|
@@ -213,11 +226,17 @@ class YoursForm(TreeNodeForm):
|
|
213
226
|
- [`update_tree`](#update_tree)
|
214
227
|
|
215
228
|
#### `delete`
|
216
|
-
**Delete a node**
|
217
|
-
|
229
|
+
**Delete a node** provides two deletion strategies:
|
230
|
+
- **Cascade Delete (`cascade=True`)**: Removes the node along with all its descendants.
|
231
|
+
- **Reparenting (`cascade=False`)**: Moves the children of the deleted node up one level in the hierarchy before removing the node itself.
|
232
|
+
|
218
233
|
```python
|
219
|
-
|
234
|
+
node.delete(cascade=True) # Deletes node and all its descendants
|
235
|
+
node.delete(cascade=False) # Moves children up and then deletes the node
|
220
236
|
```
|
237
|
+
This ensures greater flexibility in managing tree structures while preventing orphaned nodes.
|
238
|
+
|
239
|
+
---
|
221
240
|
|
222
241
|
#### `delete_tree`
|
223
242
|
**Delete the whole tree** for the current node class:
|
@@ -339,6 +358,8 @@ obj.get_descendants_tree()
|
|
339
358
|
obj.descendants_tree
|
340
359
|
```
|
341
360
|
|
361
|
+
**Important**: In future projects, avoid using `get_descendants_tree()`. It will be removed in the next version.
|
362
|
+
|
342
363
|
#### `get_descendants_tree_display`
|
343
364
|
Get a **multiline** `string` representing the **model tree**:
|
344
365
|
```python
|
@@ -347,6 +368,8 @@ obj.get_descendants_tree_display(include_self=False, depth=None)
|
|
347
368
|
obj.descendants_tree_display
|
348
369
|
```
|
349
370
|
|
371
|
+
**Important**: In future projects, avoid using `get_descendants_tree_display()`. It will be removed in the next version.
|
372
|
+
|
350
373
|
#### `get_first_child`
|
351
374
|
Get the **first child node**:
|
352
375
|
```python
|
@@ -570,27 +593,85 @@ obj.is_sibling_of(target_obj)
|
|
570
593
|
```python
|
571
594
|
cls.update_tree()
|
572
595
|
```
|
596
|
+
## **Cache Management**
|
597
|
+
### **Overview**
|
598
|
+
In v2.0, the caching mechanism has been improved to prevent excessive memory usage when multiple models inherit from `TreeNode`. The new system introduces **FIFO (First-In-First-Out) cache eviction**, with plans to test and integrate more advanced algorithms in future releases.
|
599
|
+
|
600
|
+
### **Key Features**
|
601
|
+
**Global Cache Limit**: The setting `TREENODE_CACHE_LIMIT` defines the maximum cache size (in MB) for all models inheriting from `TreeNode`. Default is **100MB** if not explicitly set in `settings.py`.
|
602
|
+
**settings.py**
|
603
|
+
``` python
|
604
|
+
TREENODE_CACHE_LIMIT = 100
|
605
|
+
```
|
606
|
+
**Automatic Management**: In most cases, users don’t need to manually manage cache operations.
|
607
|
+
**Manual Cache Clearing**:
|
608
|
+
- **Clear cache for a single model**: Use `clear_cache()` at the model level:
|
609
|
+
```python
|
610
|
+
MyTreeNodeModel.clear_cache()
|
611
|
+
```
|
612
|
+
- **Clear cache for all models**: Use the global `treenode_cache.clear()` method:
|
613
|
+
```python
|
614
|
+
from treenode.cache import treenode_cache
|
615
|
+
treenode_cache.clear()
|
616
|
+
```
|
617
|
+
|
618
|
+
## **Export and Import Functionality**
|
619
|
+
### **Overview**
|
620
|
+
TreeNode v2.0 includes **built-in export and import features** for easier data migration. Supported Formats: `csv`, `json`, `xlsx`, `yaml`, `tsv`
|
621
|
+
### Installation for Import/Export Features
|
622
|
+
By default, import/export functionality is **not included** to keep the package lightweight. If you need these features, install the package with:
|
623
|
+
```bash
|
624
|
+
pip install django-fast-treenode[import_export]
|
625
|
+
```
|
626
|
+
Once installed, **import/export buttons will appear** in the Django admin interface.
|
627
|
+
### **Important Considerations**
|
628
|
+
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.
|
629
|
+
|
630
|
+
## Migration Guide
|
631
|
+
#### Switching from `django-treenode`
|
632
|
+
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. In exceptional cases, you can call the update code `cls.update_tree()` manually.
|
633
|
+
|
634
|
+
|
635
|
+
#### Upgrading to `django-fast-treenode` 2.0
|
636
|
+
To upgrade to version 2.0, simply run:
|
637
|
+
```bash
|
638
|
+
pip install --upgrade django-fast-treenode
|
639
|
+
```
|
640
|
+
or
|
641
|
+
```bash
|
642
|
+
pip install django-fast-treenode[import_export]
|
643
|
+
```
|
644
|
+
After upgrading, ensure that your database schema is up to date by running:
|
645
|
+
```bash
|
646
|
+
python manage.py makemigrations
|
647
|
+
python manage.py migrate
|
648
|
+
```
|
649
|
+
This will apply any necessary database changes automatically.
|
573
650
|
|
574
|
-
## License
|
575
|
-
Released under [MIT License](https://github.com/TimurKady/django-fast-treenode/blob/main/LICENSE).
|
576
651
|
|
577
|
-
##
|
578
|
-
|
652
|
+
## To do
|
653
|
+
These improvements aim to enhance usability, performance, and maintainability for all users of `django-fast-treenode`:
|
654
|
+
* **Cache Algorithm Optimization**: Testing and integrating more advanced cache eviction strategies.
|
655
|
+
* **Drag-and-Drop UI Enhancements**: Adding intuitive drag-and-drop functionality for tree node management.
|
656
|
+
* to be happy, to don't worry, until die.
|
579
657
|
|
580
|
-
|
658
|
+
Your wishes, objections, comments are welcome.
|
581
659
|
|
582
|
-
## Credits
|
583
|
-
This software contains, uses, including in a modified form:
|
584
|
-
* [django-treenode](https://github.com/fabiocaccamo/django-treenode) by [Fabio Caccamo](https://github.com/fabiocaccamo);
|
585
|
-
* [Select2-to-Tree](https://github.com/clivezhg/select2-to-tree) Select2 extension by [clivezhg](https://github.com/clivezhg)
|
586
660
|
|
587
|
-
|
661
|
+
# Django-fast-treenode
|
588
662
|
|
589
|
-
##
|
590
|
-
|
591
|
-
* may be will add the ability to determine the priority of the parent by any field, for example, by creation date or alphabetical order;
|
592
|
-
* drug-and-drop support;
|
593
|
-
* to be happy, to don't worry, until die.
|
663
|
+
## License
|
664
|
+
Released under [MIT License](https://github.com/TimurKady/django-fast-treenode/blob/main/LICENSE).
|
594
665
|
|
666
|
+
## Cautions
|
667
|
+
**Warning**: Do not access the tree node fields directly! Most of *django-treenode* model fields have been removed as unnecessary. Now only `tn_parent` and `tn_priority` are supported and will be kept in the future.
|
595
668
|
|
596
|
-
|
669
|
+
**Risks of Direct Field Access:**
|
670
|
+
- **Database Integrity Issues**: Directly modifying fields may break tree integrity, causing inconsistent parent-child relationships.
|
671
|
+
- **Loss of Cached Data**: The caching system relies on controlled updates. Bypassing methods like `set_parent()` or `update_tree()` may lead to outdated or incorrect data.
|
672
|
+
- **Unsupported Behavior**: Future versions may change field structures or remove unnecessary fields. Relying on them directly risks breaking compatibility.
|
673
|
+
|
674
|
+
Instead, always use the **documented methods** described above or refer to the [original application documentation](https://github.com/fabiocaccamo/django-treenode).
|
675
|
+
|
676
|
+
## Credits
|
677
|
+
This software contains, uses, and includes, in a modified form, [django-treenode](https://github.com/fabiocaccamo/django-treenode) by [Fabio Caccamo](https://github.com/fabiocaccamo). Special thanks to [Mathieu Leplatre](https://blog.mathieu-leplatre.info/pages/about.html) for the advice used in writing this application.
|
@@ -0,0 +1,41 @@
|
|
1
|
+
treenode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
treenode/admin.py,sha256=x5vJDiZjqcsUAVlK1qkZPK66lQeJq8zYgWwwejentYM,14077
|
3
|
+
treenode/apps.py,sha256=M0O9IKEnJZFfhfz12v4wksYJ-0ECyj1Cy3qXrfywos8,472
|
4
|
+
treenode/cache.py,sha256=Z_FpaS0vTKXqAI4n1QkZ7A_ILsLU3Q8rLgerA6pYyAA,7210
|
5
|
+
treenode/forms.py,sha256=imoLzr7qFlOBdeMQK12rAFp6hINpe0PS_U4-V8RRcDU,2802
|
6
|
+
treenode/managers.py,sha256=7z8GU64A2_jEonJyQDTyIpdOocaBbM352DkwZTHjdQk,10828
|
7
|
+
treenode/urls.py,sha256=7N0d4XiI6880sc8P89eWGr-ZjmOqPorA-fWfcnviqAM,876
|
8
|
+
treenode/version.py,sha256=-zaHoXRvTvJ0QzwA9ocYp7O38iBtIarACZbCNzwyc4s,222
|
9
|
+
treenode/views.py,sha256=vBDIxmYXBwmJxRnInvUVGy75FQmt-XN_HnEaKIu-fVs,3365
|
10
|
+
treenode/widgets.py,sha256=4Q6WlPPT5fggEuTXiZ_Z40pjb46CylSp28pa0xBT_Ps,2079
|
11
|
+
treenode/docs/Documentation,sha256=ItWDx7C9KtYoXGMv782hE320sTENflrxnZjqiikr_ek,20043
|
12
|
+
treenode/models/__init__.py,sha256=gjDwVai0jf-l0hMaeeEBTYLR-DXkxUZMLUMGGs_tnuo,83
|
13
|
+
treenode/models/classproperty.py,sha256=IrwBWpmyjsAXpkpfDSOIMsnX6EMcbXql3mZjurHgRcw,556
|
14
|
+
treenode/models/closure.py,sha256=chTa9T9yC3H_2LaZXR7KLdNh1pc50iUolut5GB4Bm-Q,5297
|
15
|
+
treenode/models/factory.py,sha256=Wt1szWhbeICPwm0-RUy9p4VovcxltHECVxTSRyCQHc8,2100
|
16
|
+
treenode/models/proxy.py,sha256=6BFElk_NL1ARTEAikOOfMneUK5wEjofNnfXQWFSZUsA,21766
|
17
|
+
treenode/static/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
|
+
treenode/static/treenode/.gitkeep,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
19
|
+
treenode/static/treenode/css/.gitkeep,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
20
|
+
treenode/static/treenode/css/tree_widget.css,sha256=Qsnr9cExetL7BFKErRSns4APzM8-9DM4g6nqMelPzUI,1972
|
21
|
+
treenode/static/treenode/css/treenode_admin.css,sha256=GiCJ_zNZs7JmJgjCHsn1tJinNEU_lTOYYPZ7S0fnvis,2195
|
22
|
+
treenode/static/treenode/js/.gitkeep,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
23
|
+
treenode/static/treenode/js/tree_widget.js,sha256=Du3a76tojdIqWndji88Omt5MvajXK7GpypC9DYIFBMk,6571
|
24
|
+
treenode/static/treenode/js/treenode_admin.js,sha256=3fdvy1VoHb3rmzI19YXw4JPt6ZGKn_AhTEky8YQEilU,6821
|
25
|
+
treenode/templates/.gitkeep,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
26
|
+
treenode/templates/admin/.gitkeep,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
27
|
+
treenode/templates/admin/export_success.html,sha256=xN2D-BCH249CJB10fo_vHYUyFenQ9mFKqq7UTWcrXS4,747
|
28
|
+
treenode/templates/admin/tree_node_changelist.html,sha256=ykksipIBMy2LvH6UqPuM-y00UlXAjsypMHqiMm_KlTg,261
|
29
|
+
treenode/templates/admin/tree_node_export.html,sha256=vJxEoGI-US6VdFddxAFgL5r3MgGt6mgA43vltCsbA2k,1043
|
30
|
+
treenode/templates/admin/tree_node_import.html,sha256=ZFoveJ08X99EGiwFCfQowXI9oS9VgcFtRLYVDIWq-Fg,969
|
31
|
+
treenode/templates/widgets/tree_widget.css,sha256=2bEaxu1x7QJZ7erbs2SLMaxeaiMkjQXadfcDEW8wfok,551
|
32
|
+
treenode/templates/widgets/tree_widget.html,sha256=GKcCU-B2FkkJ2BSOuXOw9e_PdYTtADcvyITEXqOlZ9Y,723
|
33
|
+
treenode/utils/__init__.py,sha256=jAVT-uNGQDKPVq5ET4JE2GhRpzbxFdHU25w9sLC3_To,134
|
34
|
+
treenode/utils/base36.py,sha256=ydgu9hqDaK-WyS8zG-mtSWo7hJqbB4iHqkGz4-IVrb4,834
|
35
|
+
treenode/utils/exporter.py,sha256=l-IEsk2fK8xe-E-Hi7SMOV7ZIwxM6mZih5-0rhvsx9E,5396
|
36
|
+
treenode/utils/importer.py,sha256=n23PBFPXN-6S_Dl8Qmx56sp0eLy_lWfpxrzJqwygQf0,14190
|
37
|
+
django_fast_treenode-2.0.1.dist-info/LICENSE,sha256=GiiEe4Y9oOCbn9eGuNew1mMYHU_bJWaCK9zOusnKvvU,1091
|
38
|
+
django_fast_treenode-2.0.1.dist-info/METADATA,sha256=iwBXpa6Y6KqxA8n_Xc7fgpLONEp5nipoNPP9KNhH164,22225
|
39
|
+
django_fast_treenode-2.0.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
40
|
+
django_fast_treenode-2.0.1.dist-info/top_level.txt,sha256=fmgxHbXyx1O2MPi_9kjx8aL9L-8TmV0gre4Go8XgqFk,9
|
41
|
+
django_fast_treenode-2.0.1.dist-info/RECORD,,
|