django-fast-treenode 2.0.5__py3-none-any.whl → 2.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-2.0.5.dist-info → django_fast_treenode-2.0.7.dist-info}/METADATA +5 -4
- {django_fast_treenode-2.0.5.dist-info → django_fast_treenode-2.0.7.dist-info}/RECORD +7 -7
- treenode/admin.py +47 -12
- treenode/utils/__init__.py +13 -3
- {django_fast_treenode-2.0.5.dist-info → django_fast_treenode-2.0.7.dist-info}/LICENSE +0 -0
- {django_fast_treenode-2.0.5.dist-info → django_fast_treenode-2.0.7.dist-info}/WHEEL +0 -0
- {django_fast_treenode-2.0.5.dist-info → django_fast_treenode-2.0.7.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: django-fast-treenode
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.7
|
4
4
|
Summary: Application for supporting tree (hierarchical) data structure in Django projects
|
5
5
|
Home-page: https://github.com/TimurKady/django-fast-treenode
|
6
6
|
Author: Timur Kady
|
@@ -608,7 +608,7 @@ obj.is_sibling_of(target_obj)
|
|
608
608
|
```
|
609
609
|
|
610
610
|
#### `update_tree`
|
611
|
-
**Update tree** manually
|
611
|
+
**Update tree** manually:
|
612
612
|
```python
|
613
613
|
cls.update_tree()
|
614
614
|
```
|
@@ -622,8 +622,9 @@ In v2.0, the caching mechanism has been improved to prevent excessive memory usa
|
|
622
622
|
``` python
|
623
623
|
TREENODE_CACHE_LIMIT = 100
|
624
624
|
```
|
625
|
-
**Automatic Management
|
626
|
-
|
625
|
+
**Automatic Management**. In most cases, users don’t need to manually manage cache operations.All methods that somehow change the state of models reset the tree cache automatically.
|
626
|
+
|
627
|
+
**Manual Cache Clearing**. If for some reason you need to reset the cache, you can do it in two ways:
|
627
628
|
- **Clear cache for a single model**: Use `clear_cache()` at the model level:
|
628
629
|
```python
|
629
630
|
MyTreeNodeModel.clear_cache()
|
@@ -1,5 +1,5 @@
|
|
1
1
|
treenode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
treenode/admin.py,sha256=
|
2
|
+
treenode/admin.py,sha256=ltpCmPCpZpIAOX-ZIuxrleEUvBiUj7AX-jygUjGBHEs,15209
|
3
3
|
treenode/apps.py,sha256=M0O9IKEnJZFfhfz12v4wksYJ-0ECyj1Cy3qXrfywos8,472
|
4
4
|
treenode/cache.py,sha256=Z_FpaS0vTKXqAI4n1QkZ7A_ILsLU3Q8rLgerA6pYyAA,7210
|
5
5
|
treenode/forms.py,sha256=imoLzr7qFlOBdeMQK12rAFp6hINpe0PS_U4-V8RRcDU,2802
|
@@ -30,12 +30,12 @@ treenode/templates/admin/tree_node_export.html,sha256=vJxEoGI-US6VdFddxAFgL5r3Mg
|
|
30
30
|
treenode/templates/admin/tree_node_import.html,sha256=ZFoveJ08X99EGiwFCfQowXI9oS9VgcFtRLYVDIWq-Fg,969
|
31
31
|
treenode/templates/widgets/tree_widget.css,sha256=2bEaxu1x7QJZ7erbs2SLMaxeaiMkjQXadfcDEW8wfok,551
|
32
32
|
treenode/templates/widgets/tree_widget.html,sha256=GKcCU-B2FkkJ2BSOuXOw9e_PdYTtADcvyITEXqOlZ9Y,723
|
33
|
-
treenode/utils/__init__.py,sha256=
|
33
|
+
treenode/utils/__init__.py,sha256=FP7DszaIC3Xzw-7P4Q8Mc2dtQgJnIVioN9ZCbvQxw0w,322
|
34
34
|
treenode/utils/base36.py,sha256=ydgu9hqDaK-WyS8zG-mtSWo7hJqbB4iHqkGz4-IVrb4,834
|
35
35
|
treenode/utils/exporter.py,sha256=l-IEsk2fK8xe-E-Hi7SMOV7ZIwxM6mZih5-0rhvsx9E,5396
|
36
36
|
treenode/utils/importer.py,sha256=n23PBFPXN-6S_Dl8Qmx56sp0eLy_lWfpxrzJqwygQf0,14190
|
37
|
-
django_fast_treenode-2.0.
|
38
|
-
django_fast_treenode-2.0.
|
39
|
-
django_fast_treenode-2.0.
|
40
|
-
django_fast_treenode-2.0.
|
41
|
-
django_fast_treenode-2.0.
|
37
|
+
django_fast_treenode-2.0.7.dist-info/LICENSE,sha256=GiiEe4Y9oOCbn9eGuNew1mMYHU_bJWaCK9zOusnKvvU,1091
|
38
|
+
django_fast_treenode-2.0.7.dist-info/METADATA,sha256=WzpmDNemaE62W7rLqF857L5VxhfPe5hVuS27UdJ9GDM,23242
|
39
|
+
django_fast_treenode-2.0.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
40
|
+
django_fast_treenode-2.0.7.dist-info/top_level.txt,sha256=fmgxHbXyx1O2MPi_9kjx8aL9L-8TmV0gre4Go8XgqFk,9
|
41
|
+
django_fast_treenode-2.0.7.dist-info/RECORD,,
|
treenode/admin.py
CHANGED
@@ -6,7 +6,7 @@ This module provides Django admin integration for the TreeNode model.
|
|
6
6
|
It includes custom tree-based sorting, optimized queries, and
|
7
7
|
import/export functionality for hierarchical data structures.
|
8
8
|
|
9
|
-
Version: 2.0.
|
9
|
+
Version: 2.0.6
|
10
10
|
Author: Timur Kady
|
11
11
|
Email: kaduevtr@gmail.com
|
12
12
|
"""
|
@@ -81,7 +81,7 @@ class TreeNodeAdminModel(admin.ModelAdmin):
|
|
81
81
|
TREENODE_DISPLAY_MODE_INDENTATION = 'indentation'
|
82
82
|
|
83
83
|
treenode_display_mode = TREENODE_DISPLAY_MODE_ACCORDION
|
84
|
-
|
84
|
+
import_export = False # Track import/export availability
|
85
85
|
change_list_template = "admin/tree_node_changelist.html"
|
86
86
|
ordering = []
|
87
87
|
list_per_page = 1000
|
@@ -107,10 +107,25 @@ class TreeNodeAdminModel(admin.ModelAdmin):
|
|
107
107
|
"""Динамически добавляем поле `tn_order` в `list_display`."""
|
108
108
|
super().__init__(model, admin_site)
|
109
109
|
|
110
|
-
#
|
110
|
+
# If `list_display` is empty, take all `fields`
|
111
111
|
if not self.list_display:
|
112
112
|
self.list_display = [field.name for field in model._meta.fields]
|
113
113
|
|
114
|
+
# Check for necessary dependencies
|
115
|
+
self.import_export = all(
|
116
|
+
importlib.util.find_spec(pkg) is not None
|
117
|
+
for pkg in ["openpyxl", "pyyaml", "pandas"]
|
118
|
+
)
|
119
|
+
|
120
|
+
if self.import_export:
|
121
|
+
from .utils import TreeNodeImporter, TreeNodeExporter
|
122
|
+
|
123
|
+
self.TreeNodeImporter = TreeNodeImporter
|
124
|
+
self.TreeNodeExporter = TreeNodeExporter
|
125
|
+
else:
|
126
|
+
self.TreeNodeImporter = None
|
127
|
+
self.TreeNodeExporter = None
|
128
|
+
|
114
129
|
def get_queryset(self, request):
|
115
130
|
"""Override get_ueryset()."""
|
116
131
|
queryset = super().get_queryset(request)
|
@@ -182,10 +197,7 @@ class TreeNodeAdminModel(admin.ModelAdmin):
|
|
182
197
|
def changelist_view(self, request, extra_context=None):
|
183
198
|
"""Changelist View."""
|
184
199
|
extra_context = extra_context or {}
|
185
|
-
extra_context['import_export_enabled'] =
|
186
|
-
importlib.util.find_spec(pkg)
|
187
|
-
is not None for pkg in ["openpyxl", "pyyaml", "pandas"]
|
188
|
-
)
|
200
|
+
extra_context['import_export_enabled'] = self.import_export
|
189
201
|
return super().changelist_view(request, extra_context=extra_context)
|
190
202
|
|
191
203
|
def get_ordering(self, request):
|
@@ -250,12 +262,19 @@ class TreeNodeAdminModel(admin.ModelAdmin):
|
|
250
262
|
return form
|
251
263
|
|
252
264
|
def get_urls(self):
|
253
|
-
"""
|
265
|
+
"""
|
266
|
+
Extend admin URLs with custom import/export routes.
|
267
|
+
|
268
|
+
Register these URLs only if all the required packages are installed.
|
269
|
+
"""
|
254
270
|
urls = super().get_urls()
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
271
|
+
if self.import_export:
|
272
|
+
custom_urls = [
|
273
|
+
path('import/', self.import_view, name='tree_node_import'),
|
274
|
+
path('export/', self.export_view, name='tree_node_export'),
|
275
|
+
]
|
276
|
+
else:
|
277
|
+
custom_urls = []
|
259
278
|
return custom_urls + urls
|
260
279
|
|
261
280
|
def import_view(self, request):
|
@@ -265,6 +284,14 @@ class TreeNodeAdminModel(admin.ModelAdmin):
|
|
265
284
|
File upload processing, auto-detection of format, validation and data
|
266
285
|
import.
|
267
286
|
"""
|
287
|
+
if not self.import_export:
|
288
|
+
self.message_user(
|
289
|
+
request,
|
290
|
+
"Import functionality is disabled because required \
|
291
|
+
packages are not installed."
|
292
|
+
)
|
293
|
+
return redirect("..")
|
294
|
+
|
268
295
|
if request.method == 'POST':
|
269
296
|
if 'file' not in request.FILES:
|
270
297
|
return render(
|
@@ -317,6 +344,14 @@ class TreeNodeAdminModel(admin.ModelAdmin):
|
|
317
344
|
link for manual download,
|
318
345
|
and a button to go to the model page.
|
319
346
|
"""
|
347
|
+
if not self.import_export:
|
348
|
+
self.message_user(
|
349
|
+
request,
|
350
|
+
"Export functionality is disabled because required \
|
351
|
+
packages are not installed."
|
352
|
+
)
|
353
|
+
return redirect("..")
|
354
|
+
|
320
355
|
# If the download parameter is present, we give the file directly
|
321
356
|
if 'download' in request.GET:
|
322
357
|
# Get file format
|
treenode/utils/__init__.py
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
import importlib.util
|
2
|
+
|
3
|
+
extra = all(
|
4
|
+
importlib.util.find_spec(pkg) is not None
|
5
|
+
for pkg in ["openpyxl", "pyyaml", "pandas"]
|
6
|
+
)
|
7
|
+
|
8
|
+
if extra:
|
9
|
+
from .exporter import TreeNodeExporter
|
10
|
+
from .importer import TreeNodeImporter
|
11
|
+
__all__ = ["TreeNodeExporter", "TreeNodeImporter"]
|
12
|
+
else:
|
13
|
+
__all__ = []
|
3
14
|
|
4
|
-
__all__ = ["TreeNodeExporter", "TreeNodeImporter"]
|
File without changes
|
File without changes
|
File without changes
|