django-fast-treenode 1.1.0__tar.gz → 1.1.2__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. {django-fast-treenode-1.1.0/django_fast_treenode.egg-info → django-fast-treenode-1.1.2}/PKG-INFO +6 -7
  2. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/README.md +4 -3
  3. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2/django_fast_treenode.egg-info}/PKG-INFO +6 -7
  4. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/setup.cfg +1 -1
  5. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/admin.py +136 -136
  6. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/compat.py +8 -8
  7. {django-fast-treenode-1.1.0/treenode/static/treenode/css → django-fast-treenode-1.1.2/treenode/docs}/.gitkeep +1 -1
  8. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/docs/Documentation +28 -9
  9. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/forms.py +32 -32
  10. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/models.py +15 -14
  11. {django-fast-treenode-1.1.0/treenode/docs → django-fast-treenode-1.1.2/treenode/static/select2tree}/.gitkeep +1 -1
  12. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/static/treenode/.gitkeep +1 -1
  13. {django-fast-treenode-1.1.0/treenode/static/select2tree → django-fast-treenode-1.1.2/treenode/static/treenode/css}/.gitkeep +1 -1
  14. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/static/treenode/css/treenode.css +84 -84
  15. django-fast-treenode-1.1.2/treenode/static/treenode/js/.gitkeep +1 -0
  16. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/static/treenode/js/treenode.js +201 -201
  17. django-fast-treenode-1.1.2/treenode/templates/.gitkeep +1 -0
  18. django-fast-treenode-1.1.2/treenode/templates/widgets/.gitkeep +1 -0
  19. django-fast-treenode-1.1.0/treenode/static/treenode/js/.gitkeep +0 -1
  20. django-fast-treenode-1.1.0/treenode/templates/.gitkeep +0 -1
  21. django-fast-treenode-1.1.0/treenode/templates/widgets/.gitkeep +0 -1
  22. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/LICENSE +0 -0
  23. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/MANIFEST.in +0 -0
  24. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/django_fast_treenode.egg-info/SOURCES.txt +0 -0
  25. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/django_fast_treenode.egg-info/dependency_links.txt +0 -0
  26. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/django_fast_treenode.egg-info/requires.txt +0 -0
  27. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/django_fast_treenode.egg-info/top_level.txt +0 -0
  28. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/pyproject.toml +0 -0
  29. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/setup.py +0 -0
  30. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/__init__.py +0 -0
  31. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/apps.py +0 -0
  32. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/factory.py +0 -0
  33. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/managers.py +0 -0
  34. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/static/.gitkeep +0 -0
  35. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/static/select2tree/select2tree.css +0 -0
  36. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/static/select2tree/select2tree.js +0 -0
  37. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/templates/widgets/attrs.html +0 -0
  38. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/templates/widgets/options.html +0 -0
  39. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/templates/widgets/select2tree.html +0 -0
  40. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/tests.py +0 -0
  41. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/version.py +0 -0
  42. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/views.py +0 -0
  43. {django-fast-treenode-1.1.0 → django-fast-treenode-1.1.2}/treenode/widgets.py +0 -0
@@ -1,12 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-fast-treenode
3
- Version: 1.1.0
3
+ Version: 1.1.2
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
7
  Author-email: timurkady@yandex.com
8
8
  License: MIT
9
- Platform: UNKNOWN
10
9
  Classifier: Environment :: Web Environment
11
10
  Classifier: Framework :: Django
12
11
  Classifier: Framework :: Django :: 3.0
@@ -21,13 +20,15 @@ Classifier: Programming Language :: Python :: 3.9
21
20
  Requires-Python: >=3.8
22
21
  Description-Content-Type: text/markdown
23
22
  License-File: LICENSE
23
+ Requires-Dist: Django>=3.0
24
24
 
25
25
  # Django-fast-treenode
26
26
  __Combination of Adjacency List and Closure Table__
27
27
 
28
28
  ## Functions
29
29
  Application for supporting tree (hierarchical) data structure in Django projects
30
- * Faster: resource-intensive operations are cached; bulk operations are used for inserts and changes,
30
+ * fast: the fastest of the two methods is used to process requests, combining the advantages of an **Adjacency Table** and a **Closure Table**,
31
+ * even faster: the main resource-intensive operations are **cached**; **bulk operations** are used for inserts and changes,
31
32
  * synchronized: model instances in memory are automatically updated,
32
33
  * compatibility: you can easily add a tree node to existing projects using TreeNode without changing the code,
33
34
  * no dependencies,
@@ -572,9 +573,9 @@ cls.update_tree()
572
573
  Released under [MIT License](https://github.com/TimurKady/django-fast-treenode/blob/main/LICENSE).
573
574
 
574
575
  ## Cautions
575
- The code provided is intended for testing by developers and is not recommended for use in production projects. Only general tests were carried out. The risk of using the code lies entirely with you.
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.
576
577
 
577
- Don't access treenode fields directly! Most of them have been removed as unnecessary. Use functions documented in the [source application](https://github.com/fabiocaccamo/django-treenode).
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).
578
579
 
579
580
  ## Credits
580
581
  This software contains, uses, including in a modified form:
@@ -591,5 +592,3 @@ Future plans:
591
592
 
592
593
 
593
594
  Your wishes, objections, comments are welcome.
594
-
595
-
@@ -3,7 +3,8 @@ __Combination of Adjacency List and Closure Table__
3
3
 
4
4
  ## Functions
5
5
  Application for supporting tree (hierarchical) data structure in Django projects
6
- * Faster: resource-intensive operations are cached; bulk operations are used for inserts and changes,
6
+ * fast: the fastest of the two methods is used to process requests, combining the advantages of an **Adjacency Table** and a **Closure Table**,
7
+ * even faster: the main resource-intensive operations are **cached**; **bulk operations** are used for inserts and changes,
7
8
  * synchronized: model instances in memory are automatically updated,
8
9
  * compatibility: you can easily add a tree node to existing projects using TreeNode without changing the code,
9
10
  * no dependencies,
@@ -548,9 +549,9 @@ cls.update_tree()
548
549
  Released under [MIT License](https://github.com/TimurKady/django-fast-treenode/blob/main/LICENSE).
549
550
 
550
551
  ## Cautions
551
- The code provided is intended for testing by developers and is not recommended for use in production projects. Only general tests were carried out. The risk of using the code lies entirely with you.
552
+ 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.
552
553
 
553
- Don't access treenode fields directly! Most of them have been removed as unnecessary. Use functions documented in the [source application](https://github.com/fabiocaccamo/django-treenode).
554
+ **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).
554
555
 
555
556
  ## Credits
556
557
  This software contains, uses, including in a modified form:
@@ -1,12 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-fast-treenode
3
- Version: 1.1.0
3
+ Version: 1.1.2
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
7
  Author-email: timurkady@yandex.com
8
8
  License: MIT
9
- Platform: UNKNOWN
10
9
  Classifier: Environment :: Web Environment
11
10
  Classifier: Framework :: Django
12
11
  Classifier: Framework :: Django :: 3.0
@@ -21,13 +20,15 @@ Classifier: Programming Language :: Python :: 3.9
21
20
  Requires-Python: >=3.8
22
21
  Description-Content-Type: text/markdown
23
22
  License-File: LICENSE
23
+ Requires-Dist: Django>=3.0
24
24
 
25
25
  # Django-fast-treenode
26
26
  __Combination of Adjacency List and Closure Table__
27
27
 
28
28
  ## Functions
29
29
  Application for supporting tree (hierarchical) data structure in Django projects
30
- * Faster: resource-intensive operations are cached; bulk operations are used for inserts and changes,
30
+ * fast: the fastest of the two methods is used to process requests, combining the advantages of an **Adjacency Table** and a **Closure Table**,
31
+ * even faster: the main resource-intensive operations are **cached**; **bulk operations** are used for inserts and changes,
31
32
  * synchronized: model instances in memory are automatically updated,
32
33
  * compatibility: you can easily add a tree node to existing projects using TreeNode without changing the code,
33
34
  * no dependencies,
@@ -572,9 +573,9 @@ cls.update_tree()
572
573
  Released under [MIT License](https://github.com/TimurKady/django-fast-treenode/blob/main/LICENSE).
573
574
 
574
575
  ## Cautions
575
- The code provided is intended for testing by developers and is not recommended for use in production projects. Only general tests were carried out. The risk of using the code lies entirely with you.
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.
576
577
 
577
- Don't access treenode fields directly! Most of them have been removed as unnecessary. Use functions documented in the [source application](https://github.com/fabiocaccamo/django-treenode).
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).
578
579
 
579
580
  ## Credits
580
581
  This software contains, uses, including in a modified form:
@@ -591,5 +592,3 @@ Future plans:
591
592
 
592
593
 
593
594
  Your wishes, objections, comments are welcome.
594
-
595
-
@@ -4,7 +4,7 @@ tag_date = 0
4
4
 
5
5
  [metadata]
6
6
  name = django-fast-treenode
7
- version = 1.1.0
7
+ version = 1.1.2
8
8
  description = Application for supporting tree (hierarchical) data structure in Django projects
9
9
  long_description_content_type = text/markdown
10
10
  long_description = file: README.md
@@ -1,136 +1,136 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- TreeNode Admin Module
4
-
5
- """
6
-
7
- from django.contrib import admin
8
- from django.utils.safestring import mark_safe
9
- from django.contrib.admin.views.main import ChangeList
10
- from .forms import TreeNodeForm
11
-
12
-
13
- class NoPkDescOrderedChangeList(ChangeList):
14
- def get_ordering(self, request, queryset):
15
- rv = super().get_ordering(request, queryset)
16
- rv = list(rv)
17
- rv.remove('-pk') if '-pk' in rv else None
18
- return tuple()
19
-
20
- def get_queryset(self, request):
21
- qs = self.model.objects.all()
22
- return qs.select_related('tn_parent')
23
-
24
-
25
- class TreeNodeModelAdmin(admin.ModelAdmin):
26
-
27
- TREENODE_DISPLAY_MODE_ACCORDION = 'accordion'
28
- TREENODE_DISPLAY_MODE_BREADCRUMBS = 'breadcrumbs'
29
- TREENODE_DISPLAY_MODE_INDENTATION = 'indentation'
30
-
31
- treenode_display_mode = TREENODE_DISPLAY_MODE_INDENTATION
32
-
33
- form = TreeNodeForm
34
- list_per_page = 1000
35
-
36
- def get_list_display(self, request):
37
- base_list_display = super(
38
- TreeNodeModelAdmin, self).get_list_display(request)
39
- base_list_display = list(base_list_display)
40
-
41
- def treenode_field_display(obj):
42
- return self._get_treenode_field_display(request, obj)
43
-
44
- treenode_field_display.short_description = self.model._meta.verbose_name
45
- treenode_field_display.allow_tags = True
46
-
47
- if len(base_list_display) == 1 and base_list_display[0] == '__str__':
48
- return (treenode_field_display, )
49
- else:
50
- treenode_display_field = getattr(
51
- self.model, 'treenode_display_field')
52
- if len(base_list_display) >= 1 and base_list_display[0] == treenode_display_field:
53
- base_list_display.pop(0)
54
- return (treenode_field_display, ) + tuple(base_list_display)
55
-
56
- return base_list_display
57
-
58
- def get_changelist(self, request):
59
- return NoPkDescOrderedChangeList
60
-
61
- def get_ordering(self, request):
62
- return None
63
-
64
- def list_to_queryset(self, model, data):
65
- from django.db.models.base import ModelBase
66
-
67
- if not isinstance(model, ModelBase):
68
- raise ValueError(
69
- "%s must be Model" % model
70
- )
71
- if not isinstance(data, list):
72
- raise ValueError(
73
- "%s must be List Object" % data
74
- )
75
-
76
- pk_list = [obj.pk for obj in data]
77
- return model.objects.filter(pk__in=pk_list)
78
-
79
- def _use_treenode_display_mode(self, request, obj):
80
- querystring = (request.GET.urlencode() or '')
81
- return len(querystring) <= 2
82
-
83
- def _get_treenode_display_mode(self, request, obj):
84
- return self.treenode_display_mode
85
-
86
- def _get_treenode_field_default_display(self, obj):
87
- return self._get_treenode_field_display_with_breadcrumbs(obj)
88
-
89
- def _get_treenode_field_display(self, request, obj):
90
- if not self._use_treenode_display_mode(request, obj):
91
- return self._get_treenode_field_default_display(obj)
92
- display_mode = self._get_treenode_display_mode(request, obj)
93
- if display_mode == TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_ACCORDION:
94
- return self._get_treenode_field_display_with_accordion(obj)
95
- elif display_mode == TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_BREADCRUMBS:
96
- return self._get_treenode_field_display_with_breadcrumbs(obj)
97
- elif display_mode == TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_INDENTATION:
98
- return self._get_treenode_field_display_with_indentation(obj)
99
- else:
100
- return self._get_treenode_field_default_display(obj)
101
-
102
- def _get_treenode_field_display_with_accordion(self, obj):
103
- tn_namespace = '%s.%s' % (obj.__module__, obj.__class__.__name__, )
104
- tn_namespace_key = tn_namespace.lower().replace('.', '_')
105
- return mark_safe(''
106
- '<span class="treenode"'
107
- ' data-treenode-type="%s"'
108
- ' data-treenode-pk="%s"'
109
- ' data-treenode-accordion="1"'
110
- ' data-treenode-depth="%s"'
111
- ' data-treenode-level="%s"'
112
- ' data-treenode-parent="%s">%s</span>' % (
113
- tn_namespace_key,
114
- str(obj.pk),
115
- str(obj.depth),
116
- str(obj.level),
117
- str(obj.tn_parent_id or ''),
118
- obj.get_display(indent=False), ))
119
-
120
- def _get_treenode_field_display_with_breadcrumbs(self, obj):
121
- obj_display = ''
122
- for obj_ancestor in obj.get_ancestors():
123
- obj_ancestor_display = obj_ancestor.get_display(indent=False)
124
- obj_display += '<span class="treenode-breadcrumbs">%s</span>' % (
125
- obj_ancestor_display, )
126
- obj_display += obj.get_display(indent=False)
127
- return mark_safe('<span class="treenode">%s</span>' % (obj_display, ))
128
-
129
- def _get_treenode_field_display_with_indentation(self, obj):
130
- obj_display = '<span class="treenode-indentation">&mdash;</span>' * obj.ancestors_count
131
- obj_display += obj.get_display(indent=False)
132
- return mark_safe('<span class="treenode">%s</span>' % (obj_display, ))
133
-
134
- class Media:
135
- css = {'all': ('treenode/css/treenode.css',)}
136
- js = ['treenode/js/treenode.js']
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ TreeNode Admin Module
4
+
5
+ """
6
+
7
+ from django.contrib import admin
8
+ from django.utils.safestring import mark_safe
9
+ from django.contrib.admin.views.main import ChangeList
10
+ from .forms import TreeNodeForm
11
+
12
+
13
+ class NoPkDescOrderedChangeList(ChangeList):
14
+ def get_ordering(self, request, queryset):
15
+ rv = super().get_ordering(request, queryset)
16
+ rv = list(rv)
17
+ rv.remove('-pk') if '-pk' in rv else None
18
+ return tuple()
19
+
20
+ def get_queryset(self, request):
21
+ qs = self.model.objects.all()
22
+ return qs.select_related('tn_parent')
23
+
24
+
25
+ class TreeNodeModelAdmin(admin.ModelAdmin):
26
+
27
+ TREENODE_DISPLAY_MODE_ACCORDION = 'accordion'
28
+ TREENODE_DISPLAY_MODE_BREADCRUMBS = 'breadcrumbs'
29
+ TREENODE_DISPLAY_MODE_INDENTATION = 'indentation'
30
+
31
+ treenode_display_mode = TREENODE_DISPLAY_MODE_INDENTATION
32
+
33
+ form = TreeNodeForm
34
+ list_per_page = 1000
35
+
36
+ def get_list_display(self, request):
37
+ base_list_display = super(
38
+ TreeNodeModelAdmin, self).get_list_display(request)
39
+ base_list_display = list(base_list_display)
40
+
41
+ def treenode_field_display(obj):
42
+ return self._get_treenode_field_display(request, obj)
43
+
44
+ treenode_field_display.short_description = self.model._meta.verbose_name
45
+ treenode_field_display.allow_tags = True
46
+
47
+ if len(base_list_display) == 1 and base_list_display[0] == '__str__':
48
+ return (treenode_field_display, )
49
+ else:
50
+ treenode_display_field = getattr(
51
+ self.model, 'treenode_display_field')
52
+ if len(base_list_display) >= 1 and base_list_display[0] == treenode_display_field:
53
+ base_list_display.pop(0)
54
+ return (treenode_field_display, ) + tuple(base_list_display)
55
+
56
+ return base_list_display
57
+
58
+ def get_changelist(self, request):
59
+ return NoPkDescOrderedChangeList
60
+
61
+ def get_ordering(self, request):
62
+ return None
63
+
64
+ def list_to_queryset(self, model, data):
65
+ from django.db.models.base import ModelBase
66
+
67
+ if not isinstance(model, ModelBase):
68
+ raise ValueError(
69
+ "%s must be Model" % model
70
+ )
71
+ if not isinstance(data, list):
72
+ raise ValueError(
73
+ "%s must be List Object" % data
74
+ )
75
+
76
+ pk_list = [obj.pk for obj in data]
77
+ return model.objects.filter(pk__in=pk_list)
78
+
79
+ def _use_treenode_display_mode(self, request, obj):
80
+ querystring = (request.GET.urlencode() or '')
81
+ return len(querystring) <= 2
82
+
83
+ def _get_treenode_display_mode(self, request, obj):
84
+ return self.treenode_display_mode
85
+
86
+ def _get_treenode_field_default_display(self, obj):
87
+ return self._get_treenode_field_display_with_breadcrumbs(obj)
88
+
89
+ def _get_treenode_field_display(self, request, obj):
90
+ if not self._use_treenode_display_mode(request, obj):
91
+ return self._get_treenode_field_default_display(obj)
92
+ display_mode = self._get_treenode_display_mode(request, obj)
93
+ if display_mode == TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_ACCORDION:
94
+ return self._get_treenode_field_display_with_accordion(obj)
95
+ elif display_mode == TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_BREADCRUMBS:
96
+ return self._get_treenode_field_display_with_breadcrumbs(obj)
97
+ elif display_mode == TreeNodeModelAdmin.TREENODE_DISPLAY_MODE_INDENTATION:
98
+ return self._get_treenode_field_display_with_indentation(obj)
99
+ else:
100
+ return self._get_treenode_field_default_display(obj)
101
+
102
+ def _get_treenode_field_display_with_accordion(self, obj):
103
+ tn_namespace = '%s.%s' % (obj.__module__, obj.__class__.__name__, )
104
+ tn_namespace_key = tn_namespace.lower().replace('.', '_')
105
+ return mark_safe(''
106
+ '<span class="treenode"'
107
+ ' data-treenode-type="%s"'
108
+ ' data-treenode-pk="%s"'
109
+ ' data-treenode-accordion="1"'
110
+ ' data-treenode-depth="%s"'
111
+ ' data-treenode-level="%s"'
112
+ ' data-treenode-parent="%s">%s</span>' % (
113
+ tn_namespace_key,
114
+ str(obj.pk),
115
+ str(obj.depth),
116
+ str(obj.level),
117
+ str(obj.tn_parent_id or ''),
118
+ obj.get_display(indent=False), ))
119
+
120
+ def _get_treenode_field_display_with_breadcrumbs(self, obj):
121
+ obj_display = ''
122
+ for obj_ancestor in obj.get_ancestors():
123
+ obj_ancestor_display = obj_ancestor.get_display(indent=False)
124
+ obj_display += '<span class="treenode-breadcrumbs">%s</span>' % (
125
+ obj_ancestor_display, )
126
+ obj_display += obj.get_display(indent=False)
127
+ return mark_safe('<span class="treenode">%s</span>' % (obj_display, ))
128
+
129
+ def _get_treenode_field_display_with_indentation(self, obj):
130
+ obj_display = '<span class="treenode-indentation">&mdash;</span>' * obj.ancestors_count
131
+ obj_display += obj.get_display(indent=False)
132
+ return mark_safe('<span class="treenode">%s</span>' % (obj_display, ))
133
+
134
+ class Media:
135
+ css = {'all': ('treenode/css/treenode.css',)}
136
+ js = ['treenode/js/treenode.js']
@@ -1,8 +1,8 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- import django
4
-
5
- if django.VERSION >= (3, 0):
6
- from django.utils.encoding import force_str
7
- else:
8
- from django.utils.encoding import force_text as force_str
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import django
4
+
5
+ if django.VERSION >= (3, 0):
6
+ from django.utils.encoding import force_str
7
+ else:
8
+ from django.utils.encoding import force_text as force_str
@@ -1,15 +1,15 @@
1
1
  # Django-fast-treenode
2
2
  __Combination of Adjacency List and Closure Table__
3
3
 
4
- ## Functions
4
+ ## Features
5
5
  Application for supporting tree (hierarchical) data structure in Django projects
6
- * Faster: resource-intensive operations are cached; bulk operations are used for inserts and changes,
7
- * synchronized: model instances in memory are automatically updated,
8
- * compatibility: you can easily add a tree node to existing projects using TreeNode without changing the code,
6
+ * faster,
7
+ * synced: in-memory model instances are automatically updated,
8
+ * compatibility: you can easily add treenode to existing projects,
9
9
  * no dependencies,
10
- * easy setup: just extend the abstract model/model-admin,
11
- * admin integration: visualization options (accordion, breadcrumbs or padding),
12
- * widget: Built-in Select2-to-Tree extends Select2 to support arbitrary nesting levels.
10
+ * easy configuration: just extend the abstract model / model-admin,
11
+ * admin integration: visualization options (accordion, breadcrumbs or indentation),
12
+ * widget: build-in Select2-to-Tree extends Select2 to support arbitrary level of nesting.
13
13
 
14
14
  ## Debut idea
15
15
  This is a modification of the reusable [django-treenode](https://github.com/fabiocaccamo/django-treenode) application developed by [Fabio Caccamo](https://github.com/fabiocaccamo).
@@ -44,7 +44,7 @@ You can easily find additional information on your own on the Internet.
44
44
 
45
45
  ## Quick start
46
46
  1. Run ```pip install django-fast-treenode```
47
- 2. Add ```treenode``` to ```settings.INSTALLED_APPS```
47
+ 2. Add ```django-fast-treenode``` to ```settings.INSTALLED_APPS```
48
48
  3. Make your model inherit from ```treenode.models.TreeNodeModel``` (described below)
49
49
  4. Make your model-admin inherit from ```treenode.admin.TreeNodeModelAdmin``` (described below)
50
50
  5. Run python manage.py makemigrations and ```python manage.py migrate```
@@ -157,6 +157,7 @@ class YoursForm(TreeNodeForm):
157
157
  - [`get_last_child`](#get_last_child)
158
158
  - [`get_level`](#get_level)
159
159
  - [`get_order`](#get_order)
160
+ - [`get_ordered_queryset`](#get_ordered_queryset)
160
161
  - [`get_parent`](#get_parent)
161
162
  - [`get_parent_pk`](#get_parent_pk)
162
163
  - [`set_parent`](#set_parent)
@@ -360,6 +361,23 @@ obj.get_order()
360
361
  obj.order
361
362
  ```
362
363
 
364
+ #### `get_ordered_queryset`
365
+ Returns a queryset of nodes ordered by tn_priority each node.
366
+ ```python
367
+ cls.get_ordered_queryset()
368
+ ```
369
+ For example:
370
+ - A.1
371
+ - A.1.1
372
+ - A.1.1.1
373
+ - A.1.1.2
374
+ - A.2
375
+ - A.2.1
376
+ - ...
377
+
378
+ This method uses a lot of memory, ```RawSQL()``` and ```.extra()``` QuerySet method. Use of this method is deprecated due to concerns that Django's ```.extra()``` method **will be deprecated in the future**.
379
+ Use it only if you cannot otherwise assemble an ordered tree from an Adjacency Table and a Closure Table. In most cases, the data in one Adjacency Table is sufficient for such an assembly. You can easily find the corresponding algorithms (two-pass and one-pass) on the Internet.
380
+
363
381
  #### `get_parent`
364
382
  Get the **parent node**:
365
383
  ```python
@@ -561,8 +579,9 @@ Special thanks to [Mathieu Leplatre](https://blog.mathieu-leplatre.info/pages/ab
561
579
 
562
580
  ## To do
563
581
  Future plans:
564
- * may be will add the ability to determine the priority of the parent by any field, for example, by creation date or alphabetical order;
565
582
  * drug-and-drop support;
583
+ * may be will restore caching;
584
+ * may be will add the ability to determine the priority of the parent by any field, for example, by creation date or alphabetical order;
566
585
  * to be happy, to don't worry, until die.
567
586
 
568
587
 
@@ -1,32 +1,32 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- from django import forms
4
- from .widgets import TreeWidget
5
-
6
-
7
- class TreeNodeForm(forms.ModelForm):
8
-
9
- def __init__(self, *args, **kwargs):
10
-
11
- super(TreeNodeForm, self).__init__(*args, **kwargs)
12
-
13
- if 'tn_parent' not in self.fields:
14
- return
15
- exclude_pks = []
16
- obj = self.instance
17
- if obj.pk:
18
- exclude_pks += [obj.pk]
19
- # tn_get_descendants_pks changed to get_descendants_pks()
20
- # exclude_pks += split_pks(obj.get_descendants_pks())
21
- exclude_pks += obj.get_descendants_pks()
22
-
23
- # Cheaged to "legal" call
24
- manager = obj._meta.model.objects
25
-
26
- self.fields['tn_parent'].queryset = manager.prefetch_related(
27
- 'tn_children').exclude(pk__in=exclude_pks)
28
-
29
- class Meta:
30
- widgets = {
31
- 'tn_parent': TreeWidget(attrs={'style': 'min-width:400px'}),
32
- }
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from django import forms
4
+ from .widgets import TreeWidget
5
+
6
+
7
+ class TreeNodeForm(forms.ModelForm):
8
+
9
+ def __init__(self, *args, **kwargs):
10
+
11
+ super(TreeNodeForm, self).__init__(*args, **kwargs)
12
+
13
+ if 'tn_parent' not in self.fields:
14
+ return
15
+ exclude_pks = []
16
+ obj = self.instance
17
+ if obj.pk:
18
+ exclude_pks += [obj.pk]
19
+ # tn_get_descendants_pks changed to get_descendants_pks()
20
+ # exclude_pks += split_pks(obj.get_descendants_pks())
21
+ exclude_pks += obj.get_descendants_pks()
22
+
23
+ # Cheaged to "legal" call
24
+ manager = obj._meta.model.objects
25
+
26
+ self.fields['tn_parent'].queryset = manager.prefetch_related(
27
+ 'tn_children').exclude(pk__in=exclude_pks)
28
+
29
+ class Meta:
30
+ widgets = {
31
+ 'tn_parent': TreeWidget(attrs={'style': 'min-width:400px'}),
32
+ }