django-fast-treenode 3.0.6__py3-none-any.whl → 3.0.7__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.
- {django_fast_treenode-3.0.6.dist-info → django_fast_treenode-3.0.7.dist-info}/METADATA +1 -1
- {django_fast_treenode-3.0.6.dist-info → django_fast_treenode-3.0.7.dist-info}/RECORD +27 -27
- {django_fast_treenode-3.0.6.dist-info → django_fast_treenode-3.0.7.dist-info}/WHEEL +1 -1
- treenode/__init__.py +1 -0
- treenode/admin/admin.py +23 -5
- treenode/admin/mixin.py +1 -1
- treenode/managers/queries.py +18 -6
- treenode/models/models.py +2 -2
- treenode/static/vendors/jquery-ui/AUTHORS.txt +384 -384
- treenode/static/vendors/jquery-ui/LICENSE.txt +43 -43
- treenode/static/vendors/jquery-ui/external/jquery/jquery.js +10716 -10716
- treenode/static/vendors/jquery-ui/index.html +297 -297
- treenode/static/vendors/jquery-ui/jquery-ui.css +438 -438
- treenode/static/vendors/jquery-ui/jquery-ui.js +5222 -5222
- treenode/static/vendors/jquery-ui/jquery-ui.min.css +6 -6
- treenode/static/vendors/jquery-ui/jquery-ui.min.js +5 -5
- treenode/static/vendors/jquery-ui/jquery-ui.structure.css +16 -16
- treenode/static/vendors/jquery-ui/jquery-ui.structure.min.css +4 -4
- treenode/static/vendors/jquery-ui/jquery-ui.theme.css +439 -439
- treenode/static/vendors/jquery-ui/jquery-ui.theme.min.css +4 -4
- treenode/static/vendors/jquery-ui/package.json +82 -82
- treenode/utils/db/sqlcompat.py +1 -33
- treenode/utils/db/sqlquery.py +0 -24
- treenode/version.py +2 -2
- treenode/widgets.py +0 -2
- {django_fast_treenode-3.0.6.dist-info → django_fast_treenode-3.0.7.dist-info}/licenses/LICENSE +0 -0
- {django_fast_treenode-3.0.6.dist-info → django_fast_treenode-3.0.7.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
|
|
1
|
-
django_fast_treenode-3.0.
|
2
|
-
treenode/__init__.py,sha256=
|
1
|
+
django_fast_treenode-3.0.7.dist-info/licenses/LICENSE,sha256=SSYqS84FCnAW7tAxmjBKU8qAa8Jv4VGPuSSGeHwWtJE,1095
|
2
|
+
treenode/__init__.py,sha256=3z1hWpHyy4wg6uz7HCmRi9FaXYeN5CfANVpa77UIoPw,53
|
3
3
|
treenode/apps.py,sha256=QlwjNDM9rkUoWB8Vm8-OkS6lNx0-aTByuGZlu9wrQMs,1832
|
4
4
|
treenode/cache.py,sha256=2jUiiecfFxwB7QFukpU4u0FnDzGH6hNRfo6KAYvs6vM,8447
|
5
5
|
treenode/forms.py,sha256=V-upmbYSW1BbuXdSBGExHxw_j5TTUheaHvreK9tSGTE,3155
|
@@ -7,22 +7,22 @@ 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
|
11
|
-
treenode/widgets.py,sha256=
|
10
|
+
treenode/version.py,sha256=-I7mgQs7Zf31bXpDTd5OymDS52Y_ye4ZPw9yQjKTS9E,220
|
11
|
+
treenode/widgets.py,sha256=VItPvN9XgaSRI_MZjKEmtaHDJcn2bDIQIppwKjXmYQM,4017
|
12
12
|
treenode/admin/__init__.py,sha256=XNEYHdF5lKb0vpdlVxdR2fxj5oUgzyx1YyCwsv0gxHw,100
|
13
|
-
treenode/admin/admin.py,sha256=
|
13
|
+
treenode/admin/admin.py,sha256=2-74ESGEZ7s6wfPzep6OQlz1uD_80WFExemtwbQiD3M,8289
|
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
|
-
treenode/admin/mixin.py,sha256=
|
17
|
+
treenode/admin/mixin.py,sha256=jOkKKt0CpknGokluW8T1YB7VhkCkaAAMYBuptbYDXAw,10648
|
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=
|
20
|
+
treenode/managers/queries.py,sha256=pmZ07QZQbTTJN0ur6-pQGua2vGXVCVisylL1LWNXMmo,10655
|
21
21
|
treenode/managers/tasks.py,sha256=b8deUAbCpD1Yov-PpjKNAx49rL4fejkGf64ih5JziF0,7138
|
22
22
|
treenode/models/__init__.py,sha256=iR4ksCKoayvkIWWgGk6OUGHZC3D0mzAtgdBcS2vQPBw,188
|
23
23
|
treenode/models/decorators.py,sha256=N2dcnWqSCiEXDcYCf0zVijrbGUC8kYlqOLi_GKFmECU,1457
|
24
24
|
treenode/models/factory.py,sha256=sPUSrvo1za-r6ny3B8ptwevyjO8-iUpPNrT0eSD2kvI,1786
|
25
|
-
treenode/models/models.py,sha256=
|
25
|
+
treenode/models/models.py,sha256=n_2nCJzBOEcmh3r-GCoHV3ZiTX8Xe1ewK9SPptvI_M0,12273
|
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
|
@@ -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=
|
48
|
-
treenode/static/vendors/jquery-ui/LICENSE.txt,sha256=
|
49
|
-
treenode/static/vendors/jquery-ui/index.html,sha256=
|
50
|
-
treenode/static/vendors/jquery-ui/jquery-ui.css,sha256=
|
51
|
-
treenode/static/vendors/jquery-ui/jquery-ui.js,sha256=
|
52
|
-
treenode/static/vendors/jquery-ui/jquery-ui.min.css,sha256=
|
53
|
-
treenode/static/vendors/jquery-ui/jquery-ui.min.js,sha256=
|
54
|
-
treenode/static/vendors/jquery-ui/jquery-ui.structure.css,sha256=
|
55
|
-
treenode/static/vendors/jquery-ui/jquery-ui.structure.min.css,sha256=
|
56
|
-
treenode/static/vendors/jquery-ui/jquery-ui.theme.css,sha256=
|
57
|
-
treenode/static/vendors/jquery-ui/jquery-ui.theme.min.css,sha256=
|
58
|
-
treenode/static/vendors/jquery-ui/package.json,sha256=
|
59
|
-
treenode/static/vendors/jquery-ui/external/jquery/jquery.js,sha256=
|
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
|
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
|
@@ -78,8 +78,8 @@ treenode/utils/db/__init__.py,sha256=RwicAcJSI1nhIPWLdT7j9TFsgOc9834VDn9lVn54GlY
|
|
78
78
|
treenode/utils/db/compiler.py,sha256=PgD9ybS5H8OUHw1gkFBQHhnrf5HiCx8QXUMRhydwh7o,3824
|
79
79
|
treenode/utils/db/db_vendor.py,sha256=4SyEHl51jVCDB3is4omHCf2bTB_QV3RvemUQYxJP5m0,930
|
80
80
|
treenode/utils/db/service.py,sha256=PF85Yhz2xUWFFCzpLYotmiNTZXXEH61rhswslSxEUds,2640
|
81
|
-
treenode/utils/db/sqlcompat.py,sha256=
|
82
|
-
treenode/utils/db/sqlquery.py,sha256=
|
81
|
+
treenode/utils/db/sqlcompat.py,sha256=K71ggkKIvpdTtHQ6Y4qcbo6cj2eYiEfy6DlVBr8Po1E,4460
|
82
|
+
treenode/utils/db/sqlquery.py,sha256=KXcfKbbaBF-D134H_2DiPQtjedR79SJNXPJc0msZYEc,1938
|
83
83
|
treenode/views/__init__.py,sha256=ppxbBx51TUaKstJFpAd_DTmbKjbZGmVMLNYSpgUKnd0,111
|
84
84
|
treenode/views/autoapi.py,sha256=o75e8IFsogbhZN_rbx3BKVnoruD96nWelnC5UzOqUDw,3628
|
85
85
|
treenode/views/autocomplete.py,sha256=Z7cBnC4Ihdyxm8zlbnG6CkZdVkM3TOTWRpw5mdhaIVA,1469
|
@@ -87,7 +87,7 @@ treenode/views/children.py,sha256=bygXaEBExxG3zIPL34_PYHLFFIqlQU2naqPIlyQ6e-s,11
|
|
87
87
|
treenode/views/common.py,sha256=mrmr40R91XVbMWcz5GZT-OjpnQ87F7XQZxu1W6rqpqI,617
|
88
88
|
treenode/views/crud.py,sha256=RI5rdyD4hZTszjZFThByxi_lkAeJlqbDCXFkD8iyzKE,7424
|
89
89
|
treenode/views/search.py,sha256=c_GyooT3jyoNa96bBxfoWruRN1wIw-ZGYvwGKkGojTs,1501
|
90
|
-
django_fast_treenode-3.0.
|
91
|
-
django_fast_treenode-3.0.
|
92
|
-
django_fast_treenode-3.0.
|
93
|
-
django_fast_treenode-3.0.
|
90
|
+
django_fast_treenode-3.0.7.dist-info/METADATA,sha256=7scCSnoGv6UFkQHQV1yLuZBtXr3PSU1Lii3qQi43r_o,10249
|
91
|
+
django_fast_treenode-3.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
92
|
+
django_fast_treenode-3.0.7.dist-info/top_level.txt,sha256=fmgxHbXyx1O2MPi_9kjx8aL9L-8TmV0gre4Go8XgqFk,9
|
93
|
+
django_fast_treenode-3.0.7.dist-info/RECORD,,
|
treenode/__init__.py
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
default_app_config = 'treenode.apps.TreeNodeConfig'
|
treenode/admin/admin.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
"""
|
3
3
|
TreeNode Admin Model Class
|
4
4
|
|
5
|
-
Version: 3.0.
|
5
|
+
Version: 3.0.7
|
6
6
|
Author: Timur Kady
|
7
7
|
Email: timurkady@yandex.com
|
8
8
|
"""
|
@@ -12,6 +12,7 @@ from django.contrib import admin
|
|
12
12
|
from django.db import models
|
13
13
|
from django.http import HttpResponseRedirect
|
14
14
|
from django.urls import reverse
|
15
|
+
from django.utils.html import escape
|
15
16
|
from django.utils.safestring import mark_safe
|
16
17
|
from django.utils.translation import gettext_lazy as _
|
17
18
|
|
@@ -102,10 +103,27 @@ class TreeNodeModelAdmin(AdminMixin, admin.ModelAdmin):
|
|
102
103
|
f'<span style="padding-left: {level * 1.5}em;">'
|
103
104
|
f'{icon}<a href="{edit_url}">{str(obj)}</a></span>'
|
104
105
|
)
|
105
|
-
elif self.treenode_display_mode == self.TREENODE_DISPLAY_MODE_BREADCRUMBS:
|
106
|
-
breadcrumbs = obj.
|
107
|
-
|
108
|
-
|
106
|
+
elif self.treenode_display_mode == self.TREENODE_DISPLAY_MODE_BREADCRUMBS:
|
107
|
+
breadcrumbs = obj.get_ancestors(include_self=True)
|
108
|
+
model_label = obj._meta.app_label
|
109
|
+
model_name = obj._meta.model_name
|
110
|
+
href = f"admin:{model_label}_{model_name}_change"
|
111
|
+
|
112
|
+
display_attr = getattr(obj, 'display_field', 'id')
|
113
|
+
|
114
|
+
records = [
|
115
|
+
(
|
116
|
+
getattr(item, display_attr, item.pk),
|
117
|
+
reverse(href, args=[item.pk]),
|
118
|
+
)
|
119
|
+
for item in breadcrumbs
|
120
|
+
]
|
121
|
+
|
122
|
+
content = " / ".join([
|
123
|
+
f'<a href="{url}">{escape(label)}</a>'
|
124
|
+
for label, url in records
|
125
|
+
])
|
126
|
+
|
109
127
|
elif self.treenode_display_mode == self.TREENODE_DISPLAY_MODE_INDENTATION: # noqa
|
110
128
|
indent = "—" * level
|
111
129
|
content = f'{indent}<a href="{edit_url}">{str(obj)}</a>'
|
treenode/admin/mixin.py
CHANGED
treenode/managers/queries.py
CHANGED
@@ -5,14 +5,13 @@ Low-level SQL Query Manager.
|
|
5
5
|
Encapsulates all logic to retrieve related primary keys based on relationships
|
6
6
|
(e.g., ancestors, children, descendants, siblings, family, root) using raw SQL.
|
7
7
|
|
8
|
-
Version: 3.0.
|
8
|
+
Version: 3.0.7
|
9
9
|
Author: Timur Kady
|
10
10
|
Email: timurkady@yandex.com
|
11
11
|
"""
|
12
12
|
|
13
13
|
|
14
14
|
from django.db import connection
|
15
|
-
from ..utils.db.sqlcompat import SQLCompat
|
16
15
|
|
17
16
|
|
18
17
|
class TreeQuery:
|
@@ -33,6 +32,19 @@ class TreeQuery:
|
|
33
32
|
cursor.execute(sql, params)
|
34
33
|
return cursor.fetchall()
|
35
34
|
|
35
|
+
def wrap_union_all(self, queries):
|
36
|
+
"""
|
37
|
+
Combine multiple SQL queries using UNION ALL.
|
38
|
+
|
39
|
+
Each query is a tuple: (sql, params).
|
40
|
+
Returns a tuple: (combined_sql, combined_params).
|
41
|
+
"""
|
42
|
+
union_query = " UNION ALL ".join(f"({q[0]})" for q in queries)
|
43
|
+
combined_params = []
|
44
|
+
for q in queries:
|
45
|
+
combined_params.extend(q[1])
|
46
|
+
return union_query, combined_params
|
47
|
+
|
36
48
|
def order_by(self, sql, order_by_clause):
|
37
49
|
"""Wrap the SQL in an outer query to enforce ordering."""
|
38
50
|
return f"SELECT * FROM ({sql}) AS combined ORDER BY {order_by_clause}"
|
@@ -64,7 +76,7 @@ class TreeQuery:
|
|
64
76
|
if include_self:
|
65
77
|
sql2 = f"SELECT id, priority FROM {self.db_table} WHERE id = %s"
|
66
78
|
params2 = [self.node.pk]
|
67
|
-
combined_sql, combined_params =
|
79
|
+
combined_sql, combined_params = self.wrap_union_all(
|
68
80
|
[(sql1, params1), (sql2, params2)])
|
69
81
|
sql = self.order_by(combined_sql, "priority")
|
70
82
|
return sql, combined_params
|
@@ -103,7 +115,7 @@ class TreeQuery:
|
|
103
115
|
FROM {self.db_table}
|
104
116
|
WHERE id = %s
|
105
117
|
"""
|
106
|
-
union_sql, union_params =
|
118
|
+
union_sql, union_params = self.wrap_union_all([
|
107
119
|
(base_sql, params),
|
108
120
|
(sql_self, [self.node.pk])
|
109
121
|
])
|
@@ -136,7 +148,7 @@ class TreeQuery:
|
|
136
148
|
|
137
149
|
if include_self:
|
138
150
|
sql_self = f"SELECT id, _depth, priority FROM {self.db_table} WHERE id = %s" # noqa: D501
|
139
|
-
union_sql, union_params =
|
151
|
+
union_sql, union_params = self.wrap_union_all(
|
140
152
|
[(base_sql, params), (sql_self, [self.node.pk])])
|
141
153
|
else:
|
142
154
|
union_sql, union_params = base_sql, params
|
@@ -186,7 +198,7 @@ class TreeQuery:
|
|
186
198
|
if include_self:
|
187
199
|
sql_self = f"SELECT id, _depth, priority FROM {self.db_table} WHERE id = %s" # noqa: D501
|
188
200
|
queries.append((sql_self, [self.node.pk]))
|
189
|
-
combined_sql, combined_params =
|
201
|
+
combined_sql, combined_params = self.wrap_union_all(queries)
|
190
202
|
combined_sql = self.order_by(combined_sql, "_depth, priority")
|
191
203
|
return combined_sql, combined_params
|
192
204
|
|
treenode/models/models.py
CHANGED
@@ -14,7 +14,7 @@ Features:
|
|
14
14
|
- Provides a caching mechanism to optimize performance.
|
15
15
|
- Includes methods for tree traversal, manipulation, and serialization.
|
16
16
|
|
17
|
-
Version: 3.0.
|
17
|
+
Version: 3.0.7
|
18
18
|
Author: Timur Kady
|
19
19
|
Email: timurkady@yandex.com
|
20
20
|
|
@@ -122,7 +122,7 @@ class TreeNodeModel(
|
|
122
122
|
|
123
123
|
def __str__(self):
|
124
124
|
"""Return a human-readable string representation of an object."""
|
125
|
-
field = getattr(
|
125
|
+
field = getattr(self, 'display_field', None)
|
126
126
|
if field and hasattr(self, field):
|
127
127
|
return str(getattr(self, field))
|
128
128
|
return f'Node {self.pk}'
|