django-fast-treenode 3.0.1__py3-none-any.whl → 3.0.3__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 (26) hide show
  1. {django_fast_treenode-3.0.1.dist-info → django_fast_treenode-3.0.3.dist-info}/METADATA +24 -24
  2. {django_fast_treenode-3.0.1.dist-info → django_fast_treenode-3.0.3.dist-info}/RECORD +26 -26
  3. {django_fast_treenode-3.0.1.dist-info → django_fast_treenode-3.0.3.dist-info}/WHEEL +1 -1
  4. {django_fast_treenode-3.0.1.dist-info → django_fast_treenode-3.0.3.dist-info}/licenses/LICENSE +1 -0
  5. treenode/admin/admin.py +1 -0
  6. treenode/managers/queries.py +43 -0
  7. treenode/models/mixins/descendants.py +17 -11
  8. treenode/static/vendors/jquery-ui/AUTHORS.txt +384 -384
  9. treenode/static/vendors/jquery-ui/LICENSE.txt +43 -43
  10. treenode/static/vendors/jquery-ui/external/jquery/jquery.js +10716 -10716
  11. treenode/static/vendors/jquery-ui/index.html +297 -297
  12. treenode/static/vendors/jquery-ui/jquery-ui.css +438 -438
  13. treenode/static/vendors/jquery-ui/jquery-ui.js +5222 -5222
  14. treenode/static/vendors/jquery-ui/jquery-ui.min.css +6 -6
  15. treenode/static/vendors/jquery-ui/jquery-ui.min.js +5 -5
  16. treenode/static/vendors/jquery-ui/jquery-ui.structure.css +16 -16
  17. treenode/static/vendors/jquery-ui/jquery-ui.structure.min.css +4 -4
  18. treenode/static/vendors/jquery-ui/jquery-ui.theme.css +439 -439
  19. treenode/static/vendors/jquery-ui/jquery-ui.theme.min.css +4 -4
  20. treenode/static/vendors/jquery-ui/package.json +82 -82
  21. treenode/utils/db/compiler.py +24 -25
  22. treenode/utils/db/sqlcompat.py +91 -6
  23. treenode/version.py +2 -3
  24. treenode/views/crud.py +31 -10
  25. treenode/widgets.py +2 -0
  26. {django_fast_treenode-3.0.1.dist-info → django_fast_treenode-3.0.3.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-fast-treenode
3
- Version: 3.0.1
3
+ Version: 3.0.3
4
4
  Summary: Treenode Framework for supporting tree (hierarchical) data structure in Django projects
5
5
  Home-page: https://django-fast-treenode.readthedocs.io/
6
6
  Author: Timur Kady
@@ -27,6 +27,7 @@ License: MIT License
27
27
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
28
  SOFTWARE.
29
29
 
30
+
30
31
  Project-URL: Homepage, https://github.com/TimurKady/django-fast-treenode
31
32
  Project-URL: Documentation, https://django-fast-treenode.readthedocs.io/
32
33
  Project-URL: Source, https://github.com/TimurKady/django-fast-treenode
@@ -61,16 +62,16 @@ Dynamic: home-page
61
62
  Dynamic: license-file
62
63
  Dynamic: requires-python
63
64
 
64
- # TreeNode Framework
65
+ # Treenode Framework
65
66
  **A hybrid open-source framework for working with trees in Django**
66
67
 
67
68
  [![Tests](https://github.com/TimurKady/django-fast-treenode/actions/workflows/test.yaml/badge.svg?branch=main)](https://github.com/TimurKady/django-fast-treenode/actions/workflows/test.yaml)
68
69
  [![Docs](https://readthedocs.org/projects/django-fast-treenode/badge/?version=latest)](https://django-fast-treenode.readthedocs.io/)
69
- [![PyPI](https://img.shields.io/pypi/v/django-fast-treenode.svg)](https://pypi.org/project/django-fast-treenode/)
70
+ [![PyPI](https://img.shields.io/pypi/v/django-fast-treenode.svg)](https://pypi.org/project/django-fast-Treenode/)
70
71
  [![Published on Django Packages](https://img.shields.io/badge/Published%20on-Django%20Packages-0c3c26)](https://djangopackages.org/packages/p/django-fast-treenode/)
71
72
  [![Sponsor](https://img.shields.io/github/sponsors/TimurKady)](https://github.com/sponsors/TimurKady)
72
73
 
73
- ## About The TreeNode Framework
74
+ ## About The Treenode Framework
74
75
  ### Overview
75
76
 
76
77
  **Treenode Framework** is an advanced tree management system for Django applications.It is designed to handle large-scale, deeply nested, and highly dynamic tree structures while maintaining excellent performance, data integrity, and ease of use.
@@ -86,7 +87,7 @@ Its core philosophy: **maximum scalability, minimum complexity**.
86
87
 
87
88
  ### Key Features
88
89
  #### Common operations
89
- The `django-fast-treenode` package supports all the basic operations needed to work with tree structures:
90
+ The `django-fast-Treenode` package supports all the basic operations needed to work with tree structures:
90
91
 
91
92
  - Extracting **ancestors** (queryset, list, pks, count);
92
93
  - Extracting **children** (queryset, list, pks, count);
@@ -117,10 +118,10 @@ Typical applications include:
117
118
 
118
119
  In all these domains, scalable and fast tree management is not a luxury — it's a necessity.
119
120
 
120
- ### Why TreeNode Framework?
121
+ ### Why Treenode Framework?
121
122
  At the moment, django-fast-treeenode is, if not the best, then one of the best packages for working with tree data under Djangjo.
122
123
 
123
- - **High performance**: [tests show](docs/about.md#benchmark-tests) that on trees of 5k-10k nodes with a nesting depth of 500-600 levels, **Treenode Framework** (`django-fast-treenode`) shows **performance 4-7 times better** than the main popular packages.
124
+ - **High performance**: [tests show](docs/about.md#benchmark-tests) that on trees of 5k-10k nodes with a nesting depth of 500-600 levels, **Treenode Framework** (`django-fast-Treenode`) shows **performance 4-7 times better** than the main popular packages.
124
125
  - **Flexible API**: today contains the widest set of methods for working with a tree in comparison with other packages.
125
126
  - **Convenient administration**: the admin panel interface was developed taking into account the experience of using other packages. It provides convenience and intuitiveness with ease of programming.
126
127
  - **Scalability**: **Treenode Framework** suitable for solving simple problems such as menus, directories, parsing arithmetic expressions, as well as complex problems such as program optimization, image layout, multi-step decision making problems, or machine learning..
@@ -133,7 +134,7 @@ To get started quickly, you need to follow these steps:
133
134
 
134
135
  - Simply install the package via `pip`:
135
136
  ```sh
136
- pip install django-fast-treenode
137
+ pip install django-fast-Treenode
137
138
  ```
138
139
  - Once installed, add `'treenode'` to your `INSTALLED_APPS` in **settings.py**:
139
140
  ```python {title="settings.py"}
@@ -146,9 +147,9 @@ To get started quickly, you need to follow these steps:
146
147
 
147
148
  - Open **models.py** and create your own tree class:
148
149
  ```
149
- from treenode.models import TreeNodeModel
150
+ from Treenode.models import TreenodeModel
150
151
 
151
- class MyTree(TreeNodeModel):
152
+ class MyTree(TreenodeModel):
152
153
  name = models.CharField(max_length=255)
153
154
  display_field = "name"
154
155
  ```
@@ -156,11 +157,11 @@ To get started quickly, you need to follow these steps:
156
157
  - Open **admin.py** and create a model for the admin panel
157
158
  ```
158
159
  from django.contrib import admin
159
- from treenode.admin import TreeNodeModelAdmin
160
- from .models import TestNode
160
+ from Treenode.admin import TreenodeModelAdmin
161
+ from .models import MyTree
161
162
 
162
- @admin.register(TestNode)
163
- class EntityAdmin(TreeNodeModelAdmin):
163
+ @admin.register(MyTree)
164
+ class MyTreeAdmin(TreenodeModelAdmin):
164
165
  list_display = ("name",)
165
166
  search_fields = ("name",)
166
167
  ```
@@ -175,25 +176,24 @@ To get started quickly, you need to follow these steps:
175
176
  ```sh
176
177
  python manage.py runserver
177
178
  ```
178
-
179
179
  Everything is ready, enjoy 🎉!
180
180
 
181
181
  ## Documentation
182
- Full documentation is available at **[ReadTheDocs](https://django-fast-treenode.readthedocs.io/)**.
182
+ Full documentation is available at **[ReadTheDocs](https://django-fast-Treenode.readthedocs.io/)**.
183
183
 
184
184
  Quick access links:
185
- * [Installation, configuration and fine tuning](https://django-fast-treenode.readthedocs.io/installation/)
186
- * [Model Inheritance and Extensions](https://django-fast-treenode.readthedocs.io/models/)
187
- * [Working with Admin Classes](https://django-fast-treenode.readthedocs.io/admin/)
188
- * [API Reference](https://django-fast-treenode.readthedocs.io/api/)
189
- * [Import & Export](https://django-fast-treenode.readthedocs.io/import_export/)
190
- * [Caching and working with cache](https://django-fast-treenode.readthedocs.io/cache/)
191
- * [Migration and upgrade guide](https://django-fast-treenode.readthedocs.io/migration/)
185
+ * [Installation, configuration and fine tuning](https://django-fast-Treenode.readthedocs.io/installation/)
186
+ * [Model Inheritance and Extensions](https://django-fast-Treenode.readthedocs.io/models/)
187
+ * [Working with Admin Classes](https://django-fast-Treenode.readthedocs.io/admin/)
188
+ * [API Reference](https://django-fast-Treenode.readthedocs.io/api/)
189
+ * [Import & Export](https://django-fast-Treenode.readthedocs.io/import_export/)
190
+ * [Caching and working with cache](https://django-fast-Treenode.readthedocs.io/cache/)
191
+ * [Migration and upgrade guide](https://django-fast-Treenode.readthedocs.io/migration/)
192
192
 
193
193
  Your wishes, objections, comments are welcome.
194
194
 
195
195
  ## License
196
- Released under [MIT License](https://github.com/TimurKady/django-fast-treenode/blob/main/LICENSE).
196
+ Released under [MIT License](https://github.com/TimurKady/django-fast-Treenode/blob/main/LICENSE).
197
197
 
198
198
  ## Credits
199
199
  Thanks to everyone who contributed to the development and testing of this package, as well as the Django community for their inspiration and support.
@@ -1,4 +1,4 @@
1
- django_fast_treenode-3.0.1.dist-info/licenses/LICENSE,sha256=T0evsb7y-63fg18ovdNSx3wwWWRwyluQvN9J4zFSvfE,1093
1
+ django_fast_treenode-3.0.3.dist-info/licenses/LICENSE,sha256=SSYqS84FCnAW7tAxmjBKU8qAa8Jv4VGPuSSGeHwWtJE,1095
2
2
  treenode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  treenode/apps.py,sha256=QlwjNDM9rkUoWB8Vm8-OkS6lNx0-aTByuGZlu9wrQMs,1832
4
4
  treenode/cache.py,sha256=2jUiiecfFxwB7QFukpU4u0FnDzGH6hNRfo6KAYvs6vM,8447
@@ -7,17 +7,17 @@ treenode/settings.py,sha256=oSkcKXNVd28HXrlWZIH2VYinCMq-UdCDlX4KD0Qc_Xk,631
7
7
  treenode/signals.py,sha256=ERrlKjGqhYaPYVKKRk1JBBlPFOmJKpJ6bXsJavcTlo0,518
8
8
  treenode/tests.py,sha256=2uDafv3Ns6f7Vy1ekUtgYxCZEi1KRyesZDTAFhYcX-E,63
9
9
  treenode/urls.py,sha256=krHvVigc_dxC0z5hEd2rgeH6th8jW7qJY3Qbia-419Y,240
10
- treenode/version.py,sha256=syIkHJEd3wcrPMwV3J-wvH-4jqj7npbU__LrW9HHGFM,222
11
- treenode/widgets.py,sha256=VItPvN9XgaSRI_MZjKEmtaHDJcn2bDIQIppwKjXmYQM,4017
10
+ treenode/version.py,sha256=UQel-ilvX8HzIC5S8Odk9qyR41TRS2ikVETb9NGTXN0,220
11
+ treenode/widgets.py,sha256=61ed16bVqb1_R97jekDrbKS5pDVK4nzXSDwL3CDBYEk,4075
12
12
  treenode/admin/__init__.py,sha256=XNEYHdF5lKb0vpdlVxdR2fxj5oUgzyx1YyCwsv0gxHw,100
13
- treenode/admin/admin.py,sha256=xhf6tT5Ydn6i_upUDA1A6TN_muNndCko8gzM_fNIex4,7707
13
+ treenode/admin/admin.py,sha256=9_GC6JjWRiG_G84royRGAr10BSNIAj4N_33JXdzP8IY,7733
14
14
  treenode/admin/changelist.py,sha256=KUYS9MaR8Ck_1xmMqupobxWKarrJEqmHuEG32CL01Bo,1662
15
15
  treenode/admin/exporter.py,sha256=QE74V6W3tvwA5kCvBt1MmVlLOaWh-o8EU63cgmiwD5Q,5724
16
16
  treenode/admin/importer.py,sha256=hK3D-1DZcoowGblRluGzng3n5Bf__hMsbNaIGXRpRdg,6263
17
17
  treenode/admin/mixin.py,sha256=yXcSpBEfoMYT7tuAbHhGbuqlVQkCR5RizW2bNWJ0QNM,10639
18
18
  treenode/managers/__init__.py,sha256=c7F9Ku9489Hv6lTpUY2nbyBlWFCXBWAkNBm4xTKcjL8,186
19
19
  treenode/managers/managers.py,sha256=8OaFxtajyR1d7-UHyiUbifMBEF9cjfHTIEYPkYUWmt0,7166
20
- treenode/managers/queries.py,sha256=rO-zTaIj9EQt1jrQF0lbAQeGgdvHs29gpKR6mfUX2d4,9237
20
+ treenode/managers/queries.py,sha256=Kepax8SDn7G5tOlPRWBCp5Oyp49O5iMITCMBoNCm_Ak,10655
21
21
  treenode/managers/tasks.py,sha256=gqZfqeOrdPtTJZ1q83aCFh6htfxP0XMTOkd1KWL9PVU,5227
22
22
  treenode/models/__init__.py,sha256=iR4ksCKoayvkIWWgGk6OUGHZC3D0mzAtgdBcS2vQPBw,188
23
23
  treenode/models/decorators.py,sha256=N2dcnWqSCiEXDcYCf0zVijrbGUC8kYlqOLi_GKFmECU,1457
@@ -26,7 +26,7 @@ treenode/models/models.py,sha256=4S4SFFSxuIlY1DjuGW2T_bJaOos9chp1cuJ5k4_4gPg,122
26
26
  treenode/models/mixins/__init__.py,sha256=aALVKMGAWbgMAeKWS6s-NF3L5FmRX96mQxtpthOX-Ec,805
27
27
  treenode/models/mixins/ancestors.py,sha256=9g-0nPHoiF_SX2kN4uDLdbWyw-TDCz1YqxLJngwTZOQ,1971
28
28
  treenode/models/mixins/children.py,sha256=H9iMqgucSmwLX-3O3QUj1a2PUQTmmWZ4GPPjRZ9a5E4,2399
29
- treenode/models/mixins/descendants.py,sha256=2iL3ofbr4KjCeBId7gotDBBLUU8Z2FvLMHtPjPYUUUc,1972
29
+ treenode/models/mixins/descendants.py,sha256=RKowr29JUUO3E_UDvbLbMLhbn5IUkY2eh3AXfU8XSE8,2165
30
30
  treenode/models/mixins/family.py,sha256=MB5kWRVvxU_xmSgCekveTP5Vhj4wJki8bU7hzn9RNLE,1673
31
31
  treenode/models/mixins/logical.py,sha256=gh5wv5XZDs5GWarU6g9zKXWNwji7SE3zSVNIpywDWjw,2190
32
32
  treenode/models/mixins/node.py,sha256=8kqYdFTyZK5WsSxguuX3jBo1nZehDmwIBjm38S6QJw4,8576
@@ -44,19 +44,19 @@ treenode/static/js/.gitkeep,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
44
44
  treenode/static/js/lz-string.min.js,sha256=TAnTJQd2AlLqT9M2TU7GFjnoj9SIfwLeZnpEtLkP624,4718
45
45
  treenode/static/js/tree_widget.js,sha256=2LU8IIJD5TXbWVGjCEgrj5aYnUYtwBZECzj25XLtxNc,9633
46
46
  treenode/static/js/treenode_admin.js,sha256=fkxAj50QxwpPVdQxDNxQZ5vR0goUt53h8FzOv_fjxBQ,15945
47
- treenode/static/vendors/jquery-ui/AUTHORS.txt,sha256=geZ7JfVsTJq8Wgjrcm1p56Zqjxx7PL9FkxhKiN8dQg8,14848
48
- treenode/static/vendors/jquery-ui/LICENSE.txt,sha256=9kkCXPZcjc2FiLCTeIO6elK9ttNRKUZKNqFgLrACUPE,1818
49
- treenode/static/vendors/jquery-ui/index.html,sha256=RSv8cA662qJdc02OX-UmpaBJoZrngoQqnNWVZNn9GQQ,24229
50
- treenode/static/vendors/jquery-ui/jquery-ui.css,sha256=O8mmheetXPeKUa-iDk8fdxDhs096eWIi10qLJb6OXyw,17171
51
- treenode/static/vendors/jquery-ui/jquery-ui.js,sha256=XtnlPiKuVzMh-cef76mBCNCTPqk2cIlKBgmTHfRBDog,146430
52
- treenode/static/vendors/jquery-ui/jquery-ui.min.css,sha256=Yv2MureLOGZicbgEv28X9ft9o0SRBZ84PWIgg6h_V2E,15003
53
- treenode/static/vendors/jquery-ui/jquery-ui.min.js,sha256=FT6F7DDm5J1Qz6B5fv3e8jnmx9QyyfR2qUeTptb73bA,70364
54
- treenode/static/vendors/jquery-ui/jquery-ui.structure.css,sha256=392jP1trXFqS1OVv2X50px0F8w1DeTyIvvHL9wxNXi0,328
55
- treenode/static/vendors/jquery-ui/jquery-ui.structure.min.css,sha256=cXLe7UDVCN5SvPpbb3HJdndQIk1hlWMrzyRRYO9rcLs,208
56
- treenode/static/vendors/jquery-ui/jquery-ui.theme.css,sha256=grsB4hVvwiBxnNsG1c_ocH1YK76CExOav_dn_BsxepU,17140
57
- treenode/static/vendors/jquery-ui/jquery-ui.theme.min.css,sha256=oW6e3DmGiKSNLzo3HCUnjes9ykGZ6gXEtl3LjiQIkMs,13708
58
- treenode/static/vendors/jquery-ui/package.json,sha256=AvCATruWzbwY7NsfzcUR2WqPjslGO8M7hHzTj1AYDQY,2122
59
- treenode/static/vendors/jquery-ui/external/jquery/jquery.js,sha256=eKhayi8LEQwp4NKxN-CfCh-3qOVUtJn3QNZ0TciWLP4,285314
47
+ treenode/static/vendors/jquery-ui/AUTHORS.txt,sha256=7eSHeezBdJ7Qlq0sbIvY4VRvqpMwLCAsm5ur1GqFBV8,15232
48
+ treenode/static/vendors/jquery-ui/LICENSE.txt,sha256=apBrQ--OzcBj7ylvGUYGVfV3jIaoB2ZPm63a1EU0Hko,1861
49
+ treenode/static/vendors/jquery-ui/index.html,sha256=fFm161yOy1n-_mJRFXB5oOYki_8Dlv-4ym3UZlrBiFw,24526
50
+ treenode/static/vendors/jquery-ui/jquery-ui.css,sha256=Q5bjan1qvGRnmfsMY79xzgnzXgNfHpKITyFwDwYDXTE,17609
51
+ treenode/static/vendors/jquery-ui/jquery-ui.js,sha256=wo5jyZcNCjgTOWkHAG5I-AHnELJBiMT7PB86Hkn981w,151652
52
+ treenode/static/vendors/jquery-ui/jquery-ui.min.css,sha256=FS9BPkDJmv5x5xNd4OpSxisTNOEUUC3cry5lZo9TXNU,15009
53
+ treenode/static/vendors/jquery-ui/jquery-ui.min.js,sha256=ymdFCtss_PVmZcIYetqzjnF_jiQur3VPdv4bjqIPA74,70369
54
+ treenode/static/vendors/jquery-ui/jquery-ui.structure.css,sha256=Sc38kpjVG4BhkslXC-wnctVgd7RO4NAVnNinveoLumU,344
55
+ treenode/static/vendors/jquery-ui/jquery-ui.structure.min.css,sha256=3Hh94kZQ7IgAV86zPR-eYJheU0GvPFXXa0ZHldtjim4,212
56
+ treenode/static/vendors/jquery-ui/jquery-ui.theme.css,sha256=0cqVKFAVS9NOQyqhyhpanAO_AQnoPsX715VK0iIMGDE,17579
57
+ treenode/static/vendors/jquery-ui/jquery-ui.theme.min.css,sha256=TdVk-kqTdbRzjVI7AfPMWaIJG2pOIlnZk4hUAW3bl3E,13712
58
+ treenode/static/vendors/jquery-ui/package.json,sha256=bDQqA98dfsEi83upFeZ8RipVtAraPRoxZMxcv244oQo,2204
59
+ treenode/static/vendors/jquery-ui/external/jquery/jquery.js,sha256=6440qEDaqjKqrIVfk4x21neDBVsbef6XUR5dUCKBv_E,296030
60
60
  treenode/static/vendors/jquery-ui/images/ui-icons_444444_256x240.png,sha256=YW09ms2dyfoVEOT_NEpaWXMMRLJxVIqu8hku63SoCEA,7107
61
61
  treenode/static/vendors/jquery-ui/images/ui-icons_555555_256x240.png,sha256=HP6KoU5aOllbVtaudhmNOLhBIzi_0oCuxBjwyhDATOo,7105
62
62
  treenode/static/vendors/jquery-ui/images/ui-icons_777620_256x240.png,sha256=NxKGIMNmb6YYZor0RuijQ7PTK5BoA9b5qXLjYTMFvXo,4615
@@ -72,19 +72,19 @@ treenode/templates/admin/treenode_rows.html,sha256=S1XtZXWMUdfgjDoKG7OJwZg81a_5I
72
72
  treenode/templates/widgets/tree_widget.html,sha256=GKcCU-B2FkkJ2BSOuXOw9e_PdYTtADcvyITEXqOlZ9Y,723
73
73
  treenode/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
74
  treenode/utils/db/__init__.py,sha256=RwicAcJSI1nhIPWLdT7j9TFsgOc9834VDn9lVn54GlY,247
75
- treenode/utils/db/compiler.py,sha256=jvrPE26dDDaPzcMqpQPx3JWtjKrgSyI5F8aa4-2RRzc,3854
75
+ treenode/utils/db/compiler.py,sha256=PgD9ybS5H8OUHw1gkFBQHhnrf5HiCx8QXUMRhydwh7o,3824
76
76
  treenode/utils/db/db_vendor.py,sha256=4SyEHl51jVCDB3is4omHCf2bTB_QV3RvemUQYxJP5m0,930
77
77
  treenode/utils/db/service.py,sha256=PF85Yhz2xUWFFCzpLYotmiNTZXXEH61rhswslSxEUds,2640
78
- treenode/utils/db/sqlcompat.py,sha256=tXFgaVy0IavdJ6FAMW7kKW0JyEAm-z_qka8XGWzzM6Q,1649
78
+ treenode/utils/db/sqlcompat.py,sha256=K71ggkKIvpdTtHQ6Y4qcbo6cj2eYiEfy6DlVBr8Po1E,4460
79
79
  treenode/utils/db/sqlquery.py,sha256=KXcfKbbaBF-D134H_2DiPQtjedR79SJNXPJc0msZYEc,1938
80
80
  treenode/views/__init__.py,sha256=ppxbBx51TUaKstJFpAd_DTmbKjbZGmVMLNYSpgUKnd0,111
81
81
  treenode/views/autoapi.py,sha256=o75e8IFsogbhZN_rbx3BKVnoruD96nWelnC5UzOqUDw,3628
82
82
  treenode/views/autocomplete.py,sha256=Z7cBnC4Ihdyxm8zlbnG6CkZdVkM3TOTWRpw5mdhaIVA,1469
83
83
  treenode/views/children.py,sha256=bygXaEBExxG3zIPL34_PYHLFFIqlQU2naqPIlyQ6e-s,1152
84
84
  treenode/views/common.py,sha256=mrmr40R91XVbMWcz5GZT-OjpnQ87F7XQZxu1W6rqpqI,617
85
- treenode/views/crud.py,sha256=fWuSKCj_m0tqqDWTCscX0r2Kh34-cMunm5pFdEQuu_A,6267
85
+ treenode/views/crud.py,sha256=RI5rdyD4hZTszjZFThByxi_lkAeJlqbDCXFkD8iyzKE,7424
86
86
  treenode/views/search.py,sha256=c_GyooT3jyoNa96bBxfoWruRN1wIw-ZGYvwGKkGojTs,1501
87
- django_fast_treenode-3.0.1.dist-info/METADATA,sha256=BTFwZ8cmmk_97wYl0eLsnXpQLbF8Si_JaG5DaI736rU,10245
88
- django_fast_treenode-3.0.1.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
89
- django_fast_treenode-3.0.1.dist-info/top_level.txt,sha256=fmgxHbXyx1O2MPi_9kjx8aL9L-8TmV0gre4Go8XgqFk,9
90
- django_fast_treenode-3.0.1.dist-info/RECORD,,
87
+ django_fast_treenode-3.0.3.dist-info/METADATA,sha256=kbt-jrE-L0YYYUrHJKdvCOMe-GiSnKdT3LhebaWCcqM,10249
88
+ django_fast_treenode-3.0.3.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
89
+ django_fast_treenode-3.0.3.dist-info/top_level.txt,sha256=fmgxHbXyx1O2MPi_9kjx8aL9L-8TmV0gre4Go8XgqFk,9
90
+ django_fast_treenode-3.0.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.0.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
treenode/admin/admin.py CHANGED
@@ -47,6 +47,7 @@ class TreeNodeModelAdmin(AdminMixin, admin.ModelAdmin):
47
47
  }
48
48
 
49
49
  change_list_template = "admin/treenode_changelist.html"
50
+ import_export = True
50
51
 
51
52
  class Media:
52
53
  """Meta Class."""
@@ -84,6 +84,48 @@ class TreeQuery:
84
84
  sql = self.order_by(sql1, "priority")
85
85
  return sql, params1
86
86
 
87
+ def get_descendants(self, include_self, depth):
88
+ """
89
+ Build SQL for the 'descendants'.
90
+
91
+ Relationship using startswith-like logic.
92
+ Avoids locale-dependent string comparison issues by relying on
93
+ _path LIKE 'xxx.%'.
94
+ """
95
+ like_pattern = self.node._path + '.%' # emulate startswith
96
+
97
+ base_sql = f"""
98
+ SELECT id, _depth, priority
99
+ FROM {self.db_table}
100
+ WHERE _path LIKE %s
101
+ """
102
+ params = [like_pattern]
103
+
104
+ if depth is not None:
105
+ depth_val = getattr(self.node, "_depth", None)
106
+ if depth_val is None:
107
+ depth_val = type(self.node).objects.values_list(
108
+ "_depth", flat=True).get(pk=self.node.pk)
109
+ base_sql += " AND _depth <= %s"
110
+ params.append(depth_val + depth)
111
+
112
+ if include_self:
113
+ sql_self = f"""
114
+ SELECT id, _depth, priority
115
+ FROM {self.db_table}
116
+ WHERE id = %s
117
+ """
118
+ union_sql, union_params = self.wrap_union_all([
119
+ (base_sql, params),
120
+ (sql_self, [self.node.pk])
121
+ ])
122
+ else:
123
+ union_sql, union_params = base_sql, params
124
+
125
+ union_sql = self.order_by(union_sql, "_depth, priority")
126
+ return union_sql, union_params
127
+
128
+ '''
87
129
  def get_descendants(self, include_self, depth):
88
130
  """
89
131
  Build SQL for the 'descendants' relationship.
@@ -113,6 +155,7 @@ class TreeQuery:
113
155
 
114
156
  union_sql = self.order_by(union_sql, "_depth, priority")
115
157
  return union_sql, union_params
158
+ '''
116
159
 
117
160
  def get_ancestors(self, include_self):
118
161
  """
@@ -32,17 +32,23 @@ class TreeNodeDescendantsMixin(models.Model):
32
32
  def get_descendants_queryset(self, include_self=False, depth=None):
33
33
  """Get the descendants queryset."""
34
34
  path = self.get_order() # calls refresh and gets the current _path
35
- from_path = path + '.'
36
- to_path = path + '/'
37
- options = {'_path__gte': from_path, '_path__lt': to_path}
38
- if depth:
39
- options["_depth__lt"] = depth
40
- queryset = self._meta.model.objects.filter(**options)
41
-
42
- if include_self:
43
- return self._meta.model.objects.filter(pk=self.pk) | queryset
44
- else:
45
- return queryset
35
+
36
+ # from_path = path + '.'
37
+ # to_path = path + '/'
38
+
39
+ # options = {'_path__gte': from_path, '_path__lt': to_path}
40
+ # if depth:
41
+ # options["_depth__lt"] = depth
42
+ # queryset = self._meta.model.objects.filter(**options)
43
+ # if include_self:
44
+ # return self._meta.model.objects.filter(pk=self.pk) | queryset
45
+ # else:
46
+ # return queryset
47
+
48
+ suffix = "" if include_self else '.'
49
+ path += suffix
50
+ queryset = self._meta.model.objects.filter(_path__startswith=path)
51
+ return queryset
46
52
 
47
53
  @cached_method
48
54
  def get_descendants_pks(self, include_self=False, depth=None):