django-fast-treenode 1.1.2__py3-none-any.whl → 2.0.0__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.2.dist-info → django_fast_treenode-2.0.0.dist-info}/METADATA +156 -44
  2. django_fast_treenode-2.0.0.dist-info/RECORD +41 -0
  3. {django_fast_treenode-1.1.2.dist-info → django_fast_treenode-2.0.0.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 +130 -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.2.dist-info/RECORD +0 -33
  35. treenode/compat.py +0 -8
  36. treenode/factory.py +0 -68
  37. treenode/models.py +0 -669
  38. treenode/static/select2tree/.gitkeep +0 -1
  39. treenode/static/select2tree/select2tree.css +0 -176
  40. treenode/static/select2tree/select2tree.js +0 -171
  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.2.dist-info → django_fast_treenode-2.0.0.dist-info}/LICENSE +0 -0
  49. {django_fast_treenode-1.1.2.dist-info → django_fast_treenode-2.0.0.dist-info}/top_level.txt +0 -0
  50. /treenode/{docs → templates/admin}/.gitkeep +0 -0
@@ -1,26 +1,44 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: django-fast-treenode
3
- Version: 1.1.2
3
+ Version: 2.0.0
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
16
- Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3 :: Only
18
- Classifier: Programming Language :: Python :: 3.8
19
- Classifier: Programming Language :: Python :: 3.9
20
- Requires-Python: >=3.8
7
+ Author-email: Timur Kady <kaduevtr@gmail.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
21
34
  Description-Content-Type: text/markdown
22
35
  License-File: LICENSE
23
- Requires-Dist: Django >=3.0
36
+ Requires-Dist: Django<5.0,>=3.2
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"
24
42
 
25
43
  # Django-fast-treenode
26
44
  __Combination of Adjacency List and Closure Table__
@@ -74,8 +92,7 @@ You can easily find additional information on your own on the Internet.
74
92
  4. Make your model-admin inherit from ```treenode.admin.TreeNodeModelAdmin``` (described below)
75
93
  5. Run python manage.py makemigrations and ```python manage.py migrate```
76
94
 
77
- When updating an existing project, simply call ```cls.update_tree()``` function once.
78
- 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).
79
96
 
80
97
  ## Configuration
81
98
  ### `models.py`
@@ -141,6 +158,8 @@ CACHES = {
141
158
  },
142
159
  "treenode": {
143
160
  "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
161
+ "KEY_PREFIX": "", # This is important!
162
+ "VERSION": None, # This is important!
144
163
  },
145
164
  }
146
165
  ```
@@ -148,15 +167,42 @@ CACHES = {
148
167
 
149
168
  ```
150
169
  class YoursForm(TreeNodeForm):
151
-
152
- class Meta:
153
- widgets = {
154
- 'tn_parent': TreeWidget(attrs={'style': 'min-width:400px'}),
155
- }
170
+ # Your code is here
156
171
  ```
157
172
 
158
- ## Usage
173
+ ## Updating to django-fast-treenode 2.X
174
+ ### Overview
175
+ If you are upgrading from a previous version, you need to follow these steps to ensure compatibility and proper functionality.
176
+
177
+ ### Update Process
178
+ 1. **Upgrade the package**
179
+ Run the following command to install the latest version:
180
+
181
+ ```bash
182
+ pip install --upgrade django-fast-treenode
183
+ ```
184
+
185
+ 2. **Apply database migrations**
186
+ After upgrading, you need to apply the necessary database migrations:
187
+
188
+ ```bash
189
+ python manage.py makemigrations
190
+ python manage.py migrate
191
+ ```
192
+
193
+ 3. **Restart the application**
194
+ Finally, restart your Django application to apply all changes:
195
+
196
+ ```bash
197
+ python manage.py runserver
198
+ ```
159
199
 
200
+ **Important Notes**: Failing to apply migrations (`migrate`) after upgrading may lead to errors when interacting with tree nodes.
201
+
202
+ By following these steps, you will ensure a smooth transition to the latest version of django-fast-treenode without data inconsistencies.
203
+
204
+
205
+ ## Usage
160
206
  ### Methods/Properties
161
207
 
162
208
  - [`delete`](#delete)
@@ -211,11 +257,17 @@ class YoursForm(TreeNodeForm):
211
257
  - [`update_tree`](#update_tree)
212
258
 
213
259
  #### `delete`
214
- **Delete a node** if `cascade=True` (default behaviour), children and descendants will be deleted too,
215
- otherwise children's parent will be set to `None` (then children become roots):
260
+ **Delete a node** provides two deletion strategies:
261
+ - **Cascade Delete (`cascade=True`)**: Removes the node along with all its descendants.
262
+ - **Reparenting (`cascade=False`)**: Moves the children of the deleted node up one level in the hierarchy before removing the node itself.
263
+
216
264
  ```python
217
- obj.delete(cascade=True)
265
+ node.delete(cascade=True) # Deletes node and all its descendants
266
+ node.delete(cascade=False) # Moves children up and then deletes the node
218
267
  ```
268
+ This ensures greater flexibility in managing tree structures while preventing orphaned nodes.
269
+
270
+ ---
219
271
 
220
272
  #### `delete_tree`
221
273
  **Delete the whole tree** for the current node class:
@@ -337,6 +389,8 @@ obj.get_descendants_tree()
337
389
  obj.descendants_tree
338
390
  ```
339
391
 
392
+ **Important**: In future projects, avoid using `get_descendants_tree()`. It will be removed in the next version.
393
+
340
394
  #### `get_descendants_tree_display`
341
395
  Get a **multiline** `string` representing the **model tree**:
342
396
  ```python
@@ -345,6 +399,8 @@ obj.get_descendants_tree_display(include_self=False, depth=None)
345
399
  obj.descendants_tree_display
346
400
  ```
347
401
 
402
+ **Important**: In future projects, avoid using `get_descendants_tree_display()`. It will be removed in the next version.
403
+
348
404
  #### `get_first_child`
349
405
  Get the **first child node**:
350
406
  ```python
@@ -568,27 +624,83 @@ obj.is_sibling_of(target_obj)
568
624
  ```python
569
625
  cls.update_tree()
570
626
  ```
627
+ ## **Cache Management**
628
+ ### **Overview**
629
+ 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.
630
+
631
+ ### **Key Features**
632
+ **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`.
633
+ **settings.py**
634
+ ``` python
635
+ TREENODE_CACHE_LIMIT = 100
636
+ ```
637
+ **Automatic Management**: In most cases, users don’t need to manually manage cache operations.
638
+ **Manual Cache Clearing**:
639
+ - **Clear cache for a single model**: Use `clear_cache()` at the model level:
640
+ ```python
641
+ MyTreeNodeModel.clear_cache()
642
+ ```
643
+ - **Clear cache for all models**: Use the global `treenode_cache.clear()` method:
644
+ ```python
645
+ from treenode.cache import treenode_cache
646
+ treenode_cache.clear()
647
+ ```
648
+
649
+ ## **Export and Import Functionality**
650
+ ### **Overview**
651
+ TreeNode v2.0 includes **built-in export and import features** for easier data migration. Supported Formats: `csv`, `json`, `xlsx`, `yaml`, `tsv`
652
+ ### Installation for Import/Export Features
653
+ By default, import/export functionality is **not included** to keep the package lightweight. If you need these features, install the package with:
654
+ ```bash
655
+ pip install django-fast-treenode[import_export]
656
+ ```
657
+ Once installed, **import/export buttons will appear** in the Django admin interface.
658
+ ### **Important Considerations**
659
+ 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.
660
+
661
+ ## Migration Guide
662
+ #### Switching from `django-treenode`
663
+ 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.
664
+
665
+
666
+ #### Upgrading to `django-fast-treenode` 2.0
667
+ To upgrade to version 2.0, simply run:
668
+ ```bash
669
+ pip install --upgrade django-fast-treenode
670
+ ```
671
+ or
672
+ ```bash
673
+ pip install django-fast-treenode[import_export]
674
+ ```
675
+ After upgrading, ensure that your database schema is up to date by running:
676
+ ```bash
677
+ python manage.py makemigrations
678
+ python manage.py migrate
679
+ ```
680
+ This will apply any necessary database changes automatically.
571
681
 
572
- ## License
573
- Released under [MIT License](https://github.com/TimurKady/django-fast-treenode/blob/main/LICENSE).
682
+ ## To do
683
+ These improvements aim to enhance usability, performance, and maintainability for all users of `django-fast-treenode`:
684
+ * **Cache Algorithm Optimization**: Testing and integrating more advanced cache eviction strategies.
685
+ * **Drag-and-Drop UI Enhancements**: Adding intuitive drag-and-drop functionality for tree node management.
686
+ * to be happy, to don't worry, until die.
574
687
 
575
- ## Cautions
576
- 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.
688
+ Your wishes, objections, comments are welcome.
577
689
 
578
- **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).
579
690
 
580
- ## Credits
581
- This software contains, uses, including in a modified form:
582
- * [django-treenode](https://github.com/fabiocaccamo/django-treenode) by [Fabio Caccamo](https://github.com/fabiocaccamo);
583
- * [Select2-to-Tree](https://github.com/clivezhg/select2-to-tree) Select2 extension by [clivezhg](https://github.com/clivezhg)
691
+ # Django-fast-treenode
692
+ ## License
693
+ Released under [MIT License](https://github.com/TimurKady/django-fast-treenode/blob/main/LICENSE).
584
694
 
585
- Special thanks to [Mathieu Leplatre](https://blog.mathieu-leplatre.info/pages/about.html) for the advice used in writing this application
695
+ ## Cautions
696
+ **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.
586
697
 
587
- ## To do
588
- Future plans:
589
- * may be will add the ability to determine the priority of the parent by any field, for example, by creation date or alphabetical order;
590
- * drug-and-drop support;
591
- * to be happy, to don't worry, until die.
698
+ **Risks of Direct Field Access:**
699
+ - **Database Integrity Issues**: Directly modifying fields may break tree integrity, causing inconsistent parent-child relationships.
700
+ - **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.
701
+ - **Unsupported Behavior**: Future versions may change field structures or remove unnecessary fields. Relying on them directly risks breaking compatibility.
592
702
 
703
+ Instead, always use the **documented methods** described above or refer to the [original application documentation](https://github.com/fabiocaccamo/django-treenode).
593
704
 
594
- Your wishes, objections, comments are welcome.
705
+ ## Credits
706
+ 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=6USAESU8MuY1vlj95yY8S6T0o_0RsktGv6S_0SdSkwk,21030
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.0.dist-info/LICENSE,sha256=GiiEe4Y9oOCbn9eGuNew1mMYHU_bJWaCK9zOusnKvvU,1091
38
+ django_fast_treenode-2.0.0.dist-info/METADATA,sha256=4KtUbAU7CMjjTFPk_5cv5jfkPZTID5Onf-U8p-gycr8,23215
39
+ django_fast_treenode-2.0.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
40
+ django_fast_treenode-2.0.0.dist-info/top_level.txt,sha256=fmgxHbXyx1O2MPi_9kjx8aL9L-8TmV0gre4Go8XgqFk,9
41
+ django_fast_treenode-2.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.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)