django-fast-treenode 2.0.5__py3-none-any.whl → 2.0.7__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: django-fast-treenode
3
- Version: 2.0.5
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, useful after **bulk updates**:
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**: In most cases, users don’t need to manually manage cache operations.
626
- **Manual Cache Clearing**:
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=x5vJDiZjqcsUAVlK1qkZPK66lQeJq8zYgWwwejentYM,14077
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=jAVT-uNGQDKPVq5ET4JE2GhRpzbxFdHU25w9sLC3_To,134
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.5.dist-info/LICENSE,sha256=GiiEe4Y9oOCbn9eGuNew1mMYHU_bJWaCK9zOusnKvvU,1091
38
- django_fast_treenode-2.0.5.dist-info/METADATA,sha256=sjucboSzhcI6bto4f0rvLjtKk2c5-2qQwohYSOQJWsc,23109
39
- django_fast_treenode-2.0.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
40
- django_fast_treenode-2.0.5.dist-info/top_level.txt,sha256=fmgxHbXyx1O2MPi_9kjx8aL9L-8TmV0gre4Go8XgqFk,9
41
- django_fast_treenode-2.0.5.dist-info/RECORD,,
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.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
- # Если `list_display` пустой, берем все `fields`
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'] = all(
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
- """Extend admin URLs with custom import/export routes."""
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
- custom_urls = [
256
- path('import/', self.import_view, name='tree_node_import'),
257
- path('export/', self.export_view, name='tree_node_export'),
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
@@ -1,4 +1,14 @@
1
- from .exporter import TreeNodeExporter
2
- from .importer import TreeNodeImporter
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"]