django-fast-treenode 1.1.3__py3-none-any.whl → 2.0.1__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.
Files changed (50) hide show
  1. {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.1.dist-info}/METADATA +127 -46
  2. django_fast_treenode-2.0.1.dist-info/RECORD +41 -0
  3. {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.1.dist-info}/WHEEL +1 -1
  4. treenode/__init__.py +0 -7
  5. treenode/admin.py +327 -82
  6. treenode/apps.py +20 -3
  7. treenode/cache.py +231 -0
  8. treenode/docs/Documentation +101 -54
  9. treenode/forms.py +75 -19
  10. treenode/managers.py +260 -48
  11. treenode/models/__init__.py +7 -0
  12. treenode/models/classproperty.py +24 -0
  13. treenode/models/closure.py +168 -0
  14. treenode/models/factory.py +71 -0
  15. treenode/models/proxy.py +650 -0
  16. treenode/static/treenode/css/tree_widget.css +62 -0
  17. treenode/static/treenode/css/treenode_admin.css +106 -0
  18. treenode/static/treenode/js/tree_widget.js +161 -0
  19. treenode/static/treenode/js/treenode_admin.js +171 -0
  20. treenode/templates/admin/export_success.html +26 -0
  21. treenode/templates/admin/tree_node_changelist.html +11 -0
  22. treenode/templates/admin/tree_node_export.html +27 -0
  23. treenode/templates/admin/tree_node_import.html +27 -0
  24. treenode/templates/widgets/tree_widget.css +23 -0
  25. treenode/templates/widgets/tree_widget.html +21 -0
  26. treenode/urls.py +34 -0
  27. treenode/utils/__init__.py +4 -0
  28. treenode/utils/base36.py +35 -0
  29. treenode/utils/exporter.py +141 -0
  30. treenode/utils/importer.py +296 -0
  31. treenode/version.py +11 -1
  32. treenode/views.py +102 -2
  33. treenode/widgets.py +49 -27
  34. django_fast_treenode-1.1.3.dist-info/RECORD +0 -33
  35. treenode/compat.py +0 -8
  36. treenode/factory.py +0 -68
  37. treenode/models.py +0 -668
  38. treenode/static/select2tree/.gitkeep +0 -1
  39. treenode/static/select2tree/select2tree.css +0 -176
  40. treenode/static/select2tree/select2tree.js +0 -181
  41. treenode/static/treenode/css/treenode.css +0 -85
  42. treenode/static/treenode/js/treenode.js +0 -201
  43. treenode/templates/widgets/.gitkeep +0 -1
  44. treenode/templates/widgets/attrs.html +0 -7
  45. treenode/templates/widgets/options.html +0 -1
  46. treenode/templates/widgets/select2tree.html +0 -22
  47. treenode/tests.py +0 -3
  48. {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.1.dist-info}/LICENSE +0 -0
  49. {django_fast_treenode-1.1.3.dist-info → django_fast_treenode-2.0.1.dist-info}/top_level.txt +0 -0
  50. /treenode/{docs → templates/admin}/.gitkeep +0 -0
@@ -1,28 +1,44 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: django-fast-treenode
3
- Version: 1.1.3
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
- Classifier: Environment :: Web Environment
10
- Classifier: Framework :: Django
11
- Classifier: Framework :: Django :: 3.0
12
- Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Operating System :: OS Independent
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.9
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
- Classifier: Framework :: Django
20
- Classifier: Framework :: Django :: 3.0
21
- Classifier: Framework :: Django :: 4.0
22
- Requires-Python: >=3.8
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 >=3.0
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
- When updating an existing project, simply call ```cls.update_tree()``` function once.
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** if `cascade=True` (default behaviour), children and descendants will be deleted too,
217
- otherwise children's parent will be set to `None` (then children become roots):
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
- obj.delete(cascade=True)
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
- ## Cautions
578
- The provided code is already being used in production projects, even though I have only done general testing. That is why the risk of using the code lies entirely with you.
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
- **Warning**: don't access the tree node fields directly! Most of them have been removed as unnecessary. In the future, only `tn_parent` and `tn_priority` will be kept. Use the functions described in the documentation above or the documentation for the [original application](https://github.com/fabiocaccamo/django-treenode).
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
- Special thanks to [Mathieu Leplatre](https://blog.mathieu-leplatre.info/pages/about.html) for the advice used in writing this application
661
+ # Django-fast-treenode
588
662
 
589
- ## To do
590
- Future plans:
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
- Your wishes, objections, comments are welcome.
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
treenode/__init__.py CHANGED
@@ -1,7 +0,0 @@
1
- class classproperty(object):
2
-
3
- def __init__(self, getter):
4
- self.getter = getter
5
-
6
- def __get__(self, instance, owner):
7
- return self.getter(owner)