django-tabbed-admin3 3.1.0__tar.gz → 3.2.0__tar.gz

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 (66) hide show
  1. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/MANIFEST.in +1 -0
  2. django_tabbed_admin3-3.2.0/PKG-INFO +233 -0
  3. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/README.rst +12 -0
  4. django_tabbed_admin3-3.2.0/django_tabbed_admin3.egg-info/PKG-INFO +233 -0
  5. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/django_tabbed_admin3.egg-info/SOURCES.txt +1 -11
  6. django_tabbed_admin3-3.2.0/django_tabbed_admin3.egg-info/top_level.txt +1 -0
  7. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/pyproject.toml +22 -6
  8. django_tabbed_admin3-3.2.0/setup.cfg +4 -0
  9. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/admin.py +20 -35
  10. django_tabbed_admin3-3.2.0/tabbed_admin/templates/tabbed_admin/change_form.html +65 -0
  11. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/templatetags/tabbed_admin_tags.py +13 -10
  12. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/tests/admin.py +5 -15
  13. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/tests/models.py +8 -16
  14. django_tabbed_admin3-3.2.0/tabbed_admin/tests/runtests.py +50 -0
  15. django_tabbed_admin3-3.2.0/tabbed_admin/tests/tests.py +193 -0
  16. django_tabbed_admin3-3.2.0/tabbed_admin/tests/urls.py +8 -0
  17. django_tabbed_admin3-3.1.0/PKG-INFO +0 -34
  18. django_tabbed_admin3-3.1.0/django_tabbed_admin3.egg-info/PKG-INFO +0 -34
  19. django_tabbed_admin3-3.1.0/django_tabbed_admin3.egg-info/top_level.txt +0 -2
  20. django_tabbed_admin3-3.1.0/setup.cfg +0 -7
  21. django_tabbed_admin3-3.1.0/setup.py +0 -38
  22. django_tabbed_admin3-3.1.0/tabbed_admin/templates/tabbed_admin/change_form.html +0 -111
  23. django_tabbed_admin3-3.1.0/tabbed_admin/tests/runtests.py +0 -74
  24. django_tabbed_admin3-3.1.0/tabbed_admin/tests/tests.py +0 -240
  25. django_tabbed_admin3-3.1.0/tabbed_admin/tests/urls.py +0 -6
  26. django_tabbed_admin3-3.1.0/tabbed_admin_exemple/manage.py +0 -10
  27. django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/__init__.py +0 -0
  28. django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/band/__init__.py +0 -0
  29. django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/band/admin.py +0 -51
  30. django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/band/models.py +0 -58
  31. django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/settings.py +0 -109
  32. django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/urls.py +0 -22
  33. django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/wsgi.py +0 -16
  34. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/AUTHORS.txt +0 -0
  35. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/LICENSE.txt +0 -0
  36. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/django_tabbed_admin3.egg-info/dependency_links.txt +0 -0
  37. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/django_tabbed_admin3.egg-info/requires.txt +0 -0
  38. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/__init__.py +0 -0
  39. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/models.py +0 -0
  40. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/settings.py +0 -0
  41. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  42. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  43. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_55_c0402a_40x100.png +0 -0
  44. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-bg_flat_55_eeeeee_40x100.png +0 -0
  45. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_100_f8f8f8_1x400.png +0 -0
  46. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_35_dddddd_1x400.png +0 -0
  47. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-bg_glass_60_eeeeee_1x400.png +0 -0
  48. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-bg_inset-hard_75_999999_1x100.png +0 -0
  49. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-bg_inset-soft_50_c9c9c9_1x100.png +0 -0
  50. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_3383bb_256x240.png +0 -0
  51. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_444444_256x240.png +0 -0
  52. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_454545_256x240.png +0 -0
  53. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_555555_256x240.png +0 -0
  54. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_70b2e1_256x240.png +0 -0
  55. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_777620_256x240.png +0 -0
  56. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_777777_256x240.png +0 -0
  57. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_999999_256x240.png +0 -0
  58. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_cc0000_256x240.png +0 -0
  59. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_fbc856_256x240.png +0 -0
  60. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/images/ui-icons_ffffff_256x240.png +0 -0
  61. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/jquery-ui-1.11.4.min.css +0 -0
  62. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/tabbed_admin.css +0 -0
  63. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/tabbed_grappelli_admin.css +0 -0
  64. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/js/jquery-ui-1.11.4.min.js +0 -0
  65. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/templatetags/__init__.py +0 -0
  66. {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/tests/__init__.py +0 -0
@@ -3,3 +3,4 @@ include LICENSE.txt
3
3
  include README.rst
4
4
  recursive-include tabbed_admin/static *
5
5
  recursive-include tabbed_admin/templates *
6
+ prune tabbed_admin_exemple
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-tabbed-admin3
3
+ Version: 3.2.0
4
+ Summary: Easily add tabs to django admin forms. Django 6.1 compatible fork.
5
+ Author: Guillaume Pousseo (original), Michael Galler (django 4 fork)
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/mgaller/django-tabbed-admin3
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Environment :: Web Environment
10
+ Classifier: Framework :: Django
11
+ Classifier: Framework :: Django :: 4.2
12
+ Classifier: Framework :: Django :: 5.0
13
+ Classifier: Framework :: Django :: 5.1
14
+ Classifier: Framework :: Django :: 5.2
15
+ Classifier: Framework :: Django :: 6.0
16
+ Classifier: Framework :: Django :: 6.1
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/x-rst
27
+ License-File: LICENSE.txt
28
+ License-File: AUTHORS.txt
29
+ Requires-Dist: django>=4.2
30
+ Dynamic: license-file
31
+
32
+ ###################
33
+ Django tabbed admin
34
+ ###################
35
+
36
+ This is a simple fork of django-tabbed-admin https://github.com/omji/django-tabbed-admin with compatibility updates for modern Django versions.
37
+
38
+ Version 3.2 adds Django 6.1 support while retaining jQuery UI and the existing
39
+ ``TABBED_ADMIN_*`` settings. Tests cover Django 4.2, 5.0, 5.1, 5.2, 6.0 and 6.1.
40
+ The change-form template now inherits Django's form controls, actions and popup
41
+ fields instead of copying them. Projects overriding
42
+ ``tabbed_admin/change_form.html`` must update their override to use this fix.
43
+ For integration with another admin extension, ``TabbedModelAdmin.tabbed_admin_base_template``
44
+ can specify a parent template instead of ``admin/change_form.html``.
45
+ The ``tabbed_admin_base_template`` context variable takes precedence over this
46
+ attribute, allowing other admin extensions to supply the parent template.
47
+
48
+
49
+ Simple library to easilly add tabs to admin forms. It also allows users to re-order inlines and fieldsets.
50
+ Django tabbed admin is compatible with django-grappelli and django-gipsy.
51
+
52
+
53
+ *******
54
+ Install
55
+ *******
56
+
57
+ It is strongly recommanded to install this theme from GIT with PIP onto you project virtualenv.
58
+
59
+ From PyPi
60
+
61
+ .. code-block:: shell-session
62
+
63
+ pip install django-tabbed-admin3
64
+
65
+ From Github
66
+
67
+ .. code-block:: shell-session
68
+
69
+ https://github.com/mgaller/django-tabbed-admin3#egg=tabbed_admin
70
+
71
+
72
+ *****
73
+ setup
74
+ *****
75
+
76
+ Simply add the app in your installed apps list in settings.py
77
+
78
+ .. code-block:: python
79
+
80
+ INSTALLED_APPS = (
81
+ ...
82
+ 'tabbed_admin'
83
+ ...
84
+ )
85
+
86
+ Django-tabbed-admin by default requires Jquery UI tabs plugin in order to work. It is packaged with the static files required to make it funcitonnal, however, they are not activated by default to avoid a conflict with other libraries.
87
+
88
+ In order to activate the Jquery UI statics, add the following line to the project settings:
89
+
90
+ .. code-block:: python
91
+
92
+ TABBED_ADMIN_USE_JQUERY_UI = True
93
+
94
+
95
+ ********************
96
+ Configure admin tabs
97
+ ********************
98
+
99
+ In order to add tabs to a model admin, it should inherit from tabbed_admin.TabbedModelAdmin and contain a tabs attribute.
100
+ The tab attribute configuration tries to remain similar to the fieldsets and inlines setup logic.
101
+
102
+ Basically, a tuple can be created for each tab exactely the same way as for fieldsets, except that inlines can be added anywhere in between.
103
+
104
+ .. code-block:: python
105
+
106
+ tab_overview = (
107
+ (None, {
108
+ 'fields': ('name', 'bio', 'style')
109
+ }),
110
+ MusicianInline,
111
+ ('Contact', {
112
+ 'fields': ('agent', 'phone', 'email')
113
+ })
114
+ )
115
+
116
+ Then each tuple have to be passed to a *tabs* attribute prefixed by the verbose name to display within the tab:
117
+
118
+ .. code-block:: python
119
+
120
+ tabs = [
121
+ ('Overview', tab_overview),
122
+ ('Albums', tab_album)
123
+ ]
124
+
125
+
126
+ A full example would give:
127
+
128
+ .. code-block:: python
129
+
130
+ from django.contrib import admin
131
+
132
+ from tabbed_admin import TabbedModelAdmin
133
+ from .models import Band, Musician, Album
134
+
135
+
136
+ class MusicianInline(admin.StackedInline):
137
+ model = Musician
138
+ extra = 1
139
+
140
+
141
+ class AlbumInline(admin.TabularInline):
142
+ model = Album
143
+ extra = 1
144
+
145
+
146
+ @admin.register(Band)
147
+ class BandAdmin(TabbedModelAdmin):
148
+ model = Band
149
+
150
+ tab_overview = (
151
+ (None, {
152
+ 'fields': ('name', 'bio', 'style')
153
+ }),
154
+ MusicianInline,
155
+ ('Contact', {
156
+ 'fields': ('agent', 'phone', 'email')
157
+ })
158
+ )
159
+ tab_album = (
160
+ AlbumInline,
161
+ )
162
+ tabs = [
163
+ ('Overview', tab_overview),
164
+ ('Albums', tab_album)
165
+ ]
166
+
167
+ **************************
168
+ Configure tabs dynamically
169
+ **************************
170
+
171
+ Be warned that the tabs will completely reset the fieldsets and inlines attributes in order to avoid conflicts during the form saving. Both attributes are overwritten with the entries passed to the tabs attribute. For the same reasons, it is highly recommanded not to overwrite get_fieldsets or get_inlines.
172
+
173
+ You can pass and modify the tabs dynamically the same way you would do for fieldsets or inlines.
174
+
175
+ .. code-block:: python
176
+
177
+ def get_tabs(self, request, obj=None):
178
+ tabs = self.tabs
179
+ if obj is not None:
180
+ tab_overview = self.tab_overview + ('Social', {
181
+ 'fields': ('website', 'twitter', 'facebook')
182
+ })
183
+ tab_ressources = self.tab_ressources + (InterviewInline, )
184
+ tabs = [
185
+ ('Overview', tab_overview),
186
+ ('Ressources', tab_ressources)
187
+ ]
188
+ self.tabs = tabs
189
+ return super(BandAdmin, self).get_tabs(request, obj)
190
+
191
+
192
+ ********************
193
+ Change the jquery ui
194
+ ********************
195
+
196
+ You can change the jquery ui css and js by either overriding the media in the
197
+ admin class
198
+
199
+ .. code-block:: python
200
+
201
+ class Media:
202
+ css = {
203
+ 'all': ('css/jquery-ui.theme.min.css',)
204
+ }
205
+
206
+ or by changing the the following settings,
207
+
208
+ `TABBED_ADMIN_JQUERY_UI_CSS` and `TABBED_ADMIN_JQUERY_UI_JS`
209
+
210
+ .. code-block:: python
211
+
212
+ TABBED_ADMIN_JQUERY_UI_CSS = 'static/css/my-custom-jquery-ui.css'
213
+ TABBED_ADMIN_JQUERY_UI_JS = 'static/js/my-custom-jquery-ui.js'
214
+
215
+
216
+ Contribution
217
+ ************
218
+
219
+ Please feel free to contribute. Any help and advices are much appreciated.
220
+ You will find an example application to run and develop the library easily.
221
+
222
+ Run the standalone test suite with ``PYTHONPATH=. python tabbed_admin/tests/runtests.py``.
223
+
224
+
225
+ *****
226
+ LINKS
227
+ *****
228
+
229
+ Development:
230
+ https://github.com/mgaller/django-tabbed-admin3
231
+
232
+ Package:
233
+ https://pypi.python.org/pypi/django-tabbed-admin3
@@ -4,6 +4,16 @@ Django tabbed admin
4
4
 
5
5
  This is a simple fork of django-tabbed-admin https://github.com/omji/django-tabbed-admin with compatibility updates for modern Django versions.
6
6
 
7
+ Version 3.2 adds Django 6.1 support while retaining jQuery UI and the existing
8
+ ``TABBED_ADMIN_*`` settings. Tests cover Django 4.2, 5.0, 5.1, 5.2, 6.0 and 6.1.
9
+ The change-form template now inherits Django's form controls, actions and popup
10
+ fields instead of copying them. Projects overriding
11
+ ``tabbed_admin/change_form.html`` must update their override to use this fix.
12
+ For integration with another admin extension, ``TabbedModelAdmin.tabbed_admin_base_template``
13
+ can specify a parent template instead of ``admin/change_form.html``.
14
+ The ``tabbed_admin_base_template`` context variable takes precedence over this
15
+ attribute, allowing other admin extensions to supply the parent template.
16
+
7
17
 
8
18
  Simple library to easilly add tabs to admin forms. It also allows users to re-order inlines and fieldsets.
9
19
  Django tabbed admin is compatible with django-grappelli and django-gipsy.
@@ -178,6 +188,8 @@ Contribution
178
188
  Please feel free to contribute. Any help and advices are much appreciated.
179
189
  You will find an example application to run and develop the library easily.
180
190
 
191
+ Run the standalone test suite with ``PYTHONPATH=. python tabbed_admin/tests/runtests.py``.
192
+
181
193
 
182
194
  *****
183
195
  LINKS
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-tabbed-admin3
3
+ Version: 3.2.0
4
+ Summary: Easily add tabs to django admin forms. Django 6.1 compatible fork.
5
+ Author: Guillaume Pousseo (original), Michael Galler (django 4 fork)
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/mgaller/django-tabbed-admin3
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Environment :: Web Environment
10
+ Classifier: Framework :: Django
11
+ Classifier: Framework :: Django :: 4.2
12
+ Classifier: Framework :: Django :: 5.0
13
+ Classifier: Framework :: Django :: 5.1
14
+ Classifier: Framework :: Django :: 5.2
15
+ Classifier: Framework :: Django :: 6.0
16
+ Classifier: Framework :: Django :: 6.1
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/x-rst
27
+ License-File: LICENSE.txt
28
+ License-File: AUTHORS.txt
29
+ Requires-Dist: django>=4.2
30
+ Dynamic: license-file
31
+
32
+ ###################
33
+ Django tabbed admin
34
+ ###################
35
+
36
+ This is a simple fork of django-tabbed-admin https://github.com/omji/django-tabbed-admin with compatibility updates for modern Django versions.
37
+
38
+ Version 3.2 adds Django 6.1 support while retaining jQuery UI and the existing
39
+ ``TABBED_ADMIN_*`` settings. Tests cover Django 4.2, 5.0, 5.1, 5.2, 6.0 and 6.1.
40
+ The change-form template now inherits Django's form controls, actions and popup
41
+ fields instead of copying them. Projects overriding
42
+ ``tabbed_admin/change_form.html`` must update their override to use this fix.
43
+ For integration with another admin extension, ``TabbedModelAdmin.tabbed_admin_base_template``
44
+ can specify a parent template instead of ``admin/change_form.html``.
45
+ The ``tabbed_admin_base_template`` context variable takes precedence over this
46
+ attribute, allowing other admin extensions to supply the parent template.
47
+
48
+
49
+ Simple library to easilly add tabs to admin forms. It also allows users to re-order inlines and fieldsets.
50
+ Django tabbed admin is compatible with django-grappelli and django-gipsy.
51
+
52
+
53
+ *******
54
+ Install
55
+ *******
56
+
57
+ It is strongly recommanded to install this theme from GIT with PIP onto you project virtualenv.
58
+
59
+ From PyPi
60
+
61
+ .. code-block:: shell-session
62
+
63
+ pip install django-tabbed-admin3
64
+
65
+ From Github
66
+
67
+ .. code-block:: shell-session
68
+
69
+ https://github.com/mgaller/django-tabbed-admin3#egg=tabbed_admin
70
+
71
+
72
+ *****
73
+ setup
74
+ *****
75
+
76
+ Simply add the app in your installed apps list in settings.py
77
+
78
+ .. code-block:: python
79
+
80
+ INSTALLED_APPS = (
81
+ ...
82
+ 'tabbed_admin'
83
+ ...
84
+ )
85
+
86
+ Django-tabbed-admin by default requires Jquery UI tabs plugin in order to work. It is packaged with the static files required to make it funcitonnal, however, they are not activated by default to avoid a conflict with other libraries.
87
+
88
+ In order to activate the Jquery UI statics, add the following line to the project settings:
89
+
90
+ .. code-block:: python
91
+
92
+ TABBED_ADMIN_USE_JQUERY_UI = True
93
+
94
+
95
+ ********************
96
+ Configure admin tabs
97
+ ********************
98
+
99
+ In order to add tabs to a model admin, it should inherit from tabbed_admin.TabbedModelAdmin and contain a tabs attribute.
100
+ The tab attribute configuration tries to remain similar to the fieldsets and inlines setup logic.
101
+
102
+ Basically, a tuple can be created for each tab exactely the same way as for fieldsets, except that inlines can be added anywhere in between.
103
+
104
+ .. code-block:: python
105
+
106
+ tab_overview = (
107
+ (None, {
108
+ 'fields': ('name', 'bio', 'style')
109
+ }),
110
+ MusicianInline,
111
+ ('Contact', {
112
+ 'fields': ('agent', 'phone', 'email')
113
+ })
114
+ )
115
+
116
+ Then each tuple have to be passed to a *tabs* attribute prefixed by the verbose name to display within the tab:
117
+
118
+ .. code-block:: python
119
+
120
+ tabs = [
121
+ ('Overview', tab_overview),
122
+ ('Albums', tab_album)
123
+ ]
124
+
125
+
126
+ A full example would give:
127
+
128
+ .. code-block:: python
129
+
130
+ from django.contrib import admin
131
+
132
+ from tabbed_admin import TabbedModelAdmin
133
+ from .models import Band, Musician, Album
134
+
135
+
136
+ class MusicianInline(admin.StackedInline):
137
+ model = Musician
138
+ extra = 1
139
+
140
+
141
+ class AlbumInline(admin.TabularInline):
142
+ model = Album
143
+ extra = 1
144
+
145
+
146
+ @admin.register(Band)
147
+ class BandAdmin(TabbedModelAdmin):
148
+ model = Band
149
+
150
+ tab_overview = (
151
+ (None, {
152
+ 'fields': ('name', 'bio', 'style')
153
+ }),
154
+ MusicianInline,
155
+ ('Contact', {
156
+ 'fields': ('agent', 'phone', 'email')
157
+ })
158
+ )
159
+ tab_album = (
160
+ AlbumInline,
161
+ )
162
+ tabs = [
163
+ ('Overview', tab_overview),
164
+ ('Albums', tab_album)
165
+ ]
166
+
167
+ **************************
168
+ Configure tabs dynamically
169
+ **************************
170
+
171
+ Be warned that the tabs will completely reset the fieldsets and inlines attributes in order to avoid conflicts during the form saving. Both attributes are overwritten with the entries passed to the tabs attribute. For the same reasons, it is highly recommanded not to overwrite get_fieldsets or get_inlines.
172
+
173
+ You can pass and modify the tabs dynamically the same way you would do for fieldsets or inlines.
174
+
175
+ .. code-block:: python
176
+
177
+ def get_tabs(self, request, obj=None):
178
+ tabs = self.tabs
179
+ if obj is not None:
180
+ tab_overview = self.tab_overview + ('Social', {
181
+ 'fields': ('website', 'twitter', 'facebook')
182
+ })
183
+ tab_ressources = self.tab_ressources + (InterviewInline, )
184
+ tabs = [
185
+ ('Overview', tab_overview),
186
+ ('Ressources', tab_ressources)
187
+ ]
188
+ self.tabs = tabs
189
+ return super(BandAdmin, self).get_tabs(request, obj)
190
+
191
+
192
+ ********************
193
+ Change the jquery ui
194
+ ********************
195
+
196
+ You can change the jquery ui css and js by either overriding the media in the
197
+ admin class
198
+
199
+ .. code-block:: python
200
+
201
+ class Media:
202
+ css = {
203
+ 'all': ('css/jquery-ui.theme.min.css',)
204
+ }
205
+
206
+ or by changing the the following settings,
207
+
208
+ `TABBED_ADMIN_JQUERY_UI_CSS` and `TABBED_ADMIN_JQUERY_UI_JS`
209
+
210
+ .. code-block:: python
211
+
212
+ TABBED_ADMIN_JQUERY_UI_CSS = 'static/css/my-custom-jquery-ui.css'
213
+ TABBED_ADMIN_JQUERY_UI_JS = 'static/js/my-custom-jquery-ui.js'
214
+
215
+
216
+ Contribution
217
+ ************
218
+
219
+ Please feel free to contribute. Any help and advices are much appreciated.
220
+ You will find an example application to run and develop the library easily.
221
+
222
+ Run the standalone test suite with ``PYTHONPATH=. python tabbed_admin/tests/runtests.py``.
223
+
224
+
225
+ *****
226
+ LINKS
227
+ *****
228
+
229
+ Development:
230
+ https://github.com/mgaller/django-tabbed-admin3
231
+
232
+ Package:
233
+ https://pypi.python.org/pypi/django-tabbed-admin3
@@ -3,8 +3,6 @@ LICENSE.txt
3
3
  MANIFEST.in
4
4
  README.rst
5
5
  pyproject.toml
6
- setup.cfg
7
- setup.py
8
6
  django_tabbed_admin3.egg-info/PKG-INFO
9
7
  django_tabbed_admin3.egg-info/SOURCES.txt
10
8
  django_tabbed_admin3.egg-info/dependency_links.txt
@@ -46,12 +44,4 @@ tabbed_admin/tests/admin.py
46
44
  tabbed_admin/tests/models.py
47
45
  tabbed_admin/tests/runtests.py
48
46
  tabbed_admin/tests/tests.py
49
- tabbed_admin/tests/urls.py
50
- tabbed_admin_exemple/manage.py
51
- tabbed_admin_exemple/tabbed_admin_exemple/__init__.py
52
- tabbed_admin_exemple/tabbed_admin_exemple/settings.py
53
- tabbed_admin_exemple/tabbed_admin_exemple/urls.py
54
- tabbed_admin_exemple/tabbed_admin_exemple/wsgi.py
55
- tabbed_admin_exemple/tabbed_admin_exemple/band/__init__.py
56
- tabbed_admin_exemple/tabbed_admin_exemple/band/admin.py
57
- tabbed_admin_exemple/tabbed_admin_exemple/band/models.py
47
+ tabbed_admin/tests/urls.py
@@ -1,13 +1,14 @@
1
1
  [build-system]
2
- requires = ["setuptools>=68.0", "wheel"]
2
+ requires = ["setuptools>=77.0", "wheel"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "django-tabbed-admin3"
7
- version = "3.1.0"
8
- description = "Easily add tabs to django admin forms. Django 6 compatible fork."
9
- readme = "README.md"
10
- license = {text = "BSD License"}
7
+ version = "3.2.0"
8
+ description = "Easily add tabs to django admin forms. Django 6.1 compatible fork."
9
+ readme = "README.rst"
10
+ license = "BSD-3-Clause"
11
+ license-files = ["LICENSE.txt", "AUTHORS.txt"]
11
12
  authors = [
12
13
  {name = "Guillaume Pousseo (original)"},
13
14
  {name = "Michael Galler (django 4 fork)"},
@@ -23,8 +24,8 @@ classifiers = [
23
24
  "Framework :: Django :: 5.1",
24
25
  "Framework :: Django :: 5.2",
25
26
  "Framework :: Django :: 6.0",
27
+ "Framework :: Django :: 6.1",
26
28
  "Intended Audience :: Developers",
27
- "License :: OSI Approved :: BSD License",
28
29
  "Operating System :: OS Independent",
29
30
  "Programming Language :: Python :: 3",
30
31
  "Programming Language :: Python :: 3.10",
@@ -39,3 +40,18 @@ Homepage = "https://github.com/mgaller/django-tabbed-admin3"
39
40
 
40
41
  [tool.setuptools.packages.find]
41
42
  include = ["tabbed_admin*"]
43
+ namespaces = false
44
+
45
+ [tool.setuptools]
46
+ include-package-data = false
47
+
48
+ [tool.setuptools.package-data]
49
+ tabbed_admin = ["templates/**/*.html", "static/**/*.css", "static/**/*.js", "static/**/*.png"]
50
+
51
+ [tool.ruff]
52
+ target-version = "py310"
53
+ line-length = 120
54
+
55
+ [tool.ruff.lint]
56
+ select = ["E", "F", "I"]
57
+ ignore = ["E501"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -2,7 +2,7 @@ from django.conf import settings
2
2
  from django.contrib.admin.options import ModelAdmin
3
3
  from django.utils.translation import gettext_lazy as _
4
4
 
5
- from .settings import USE_JQUERY_UI, JQUERY_UI_CSS, JQUERY_UI_JS
5
+ from .settings import JQUERY_UI_CSS, JQUERY_UI_JS, USE_JQUERY_UI
6
6
 
7
7
 
8
8
  class TabbedModelAdmin(ModelAdmin):
@@ -11,6 +11,7 @@ class TabbedModelAdmin(ModelAdmin):
11
11
 
12
12
  # Needs a specific template to display the tabs
13
13
  change_form_template = "tabbed_admin/change_form.html"
14
+ tabbed_admin_base_template = "admin/change_form.html"
14
15
 
15
16
  def get_fieldsets(self, request, obj=None):
16
17
  """
@@ -62,6 +63,8 @@ class TabbedModelAdmin(ModelAdmin):
62
63
  """
63
64
  if self.tabs:
64
65
  self.parse_fieldsets_inlines_from_tabs(request, obj)
66
+ else:
67
+ self.formatted_tabs = {"fields": [], "fieldsets": (), "inlines": ()}
65
68
  return self.formatted_tabs
66
69
 
67
70
  def parse_fieldsets_inlines_from_tabs(self, request, obj=None):
@@ -71,25 +74,16 @@ class TabbedModelAdmin(ModelAdmin):
71
74
  """
72
75
  tabs_fieldsets = ()
73
76
  tabs_inlines = ()
74
- self.formatted_tabs["fields"] = []
77
+ self.formatted_tabs = {"fields": []}
75
78
  for tab in self.get_tabs(request, obj):
76
79
  # Checks that each tab is formatted with 2 arguments: verbose name
77
80
  # of the tab and the tab configuration.
78
81
  if not isinstance(tab, (tuple, list)):
79
- raise TypeError(
80
- _("Each tab entry must be either a list or a tuple")
81
- )
82
+ raise TypeError(_("Each tab entry must be either a list or a tuple"))
82
83
  if len(tab) != 2:
83
- raise ValueError(
84
- _(
85
- "Each tabs entry must contain 2 arguments: "
86
- "a verbose name and the tab setup."
87
- )
88
- )
84
+ raise ValueError(_("Each tabs entry must contain 2 arguments: a verbose name and the tab setup."))
89
85
  if not isinstance(tab[1], (tuple, list)):
90
- raise TypeError(
91
- _("A tab definition must be either a list or a tuple")
92
- )
86
+ raise TypeError(_("A tab definition must be either a list or a tuple"))
93
87
  # Parse the tab configuration: if an entry is a tuple or a list
94
88
  # it's a fieldset, otherwise it's an inline class.
95
89
  formatted_tab = {"name": tab[0], "entries": []}
@@ -100,6 +94,7 @@ class TabbedModelAdmin(ModelAdmin):
100
94
  "type": "fieldset",
101
95
  "name": tab_entry[0],
102
96
  "config": tab_entry[1],
97
+ "index": len(tabs_fieldsets) - 1,
103
98
  }
104
99
  else:
105
100
  tabs_inlines = tabs_inlines + (tab_entry,)
@@ -112,29 +107,19 @@ class TabbedModelAdmin(ModelAdmin):
112
107
  self.formatted_tabs["fieldsets"] = tabs_fieldsets
113
108
  self.formatted_tabs["inlines"] = tabs_inlines
114
109
 
115
- def add_view(self, request, form_url="", extra_context=None):
116
- """
117
- Overwrites add_view to insert the tabs config for the template.
118
- """
119
- if extra_context is None:
120
- extra_context = {}
121
- extra_context.update({"tabs": self.get_formatted_tabs(request)})
122
- return super().add_view(
123
- request, form_url=form_url, extra_context=extra_context
124
- )
125
-
126
- def change_view(self, request, object_id, form_url="", extra_context=None):
127
- """
128
- Overwrites change_view to insert the tabs config for the template.
129
- """
130
- if extra_context is None:
131
- extra_context = {}
132
- extra_context.update({"tabs": self.get_formatted_tabs(request)})
133
- return super().change_view(
110
+ def render_change_form(self, request, context, add=False, change=False, form_url="", obj=None):
111
+ context = {
112
+ **context,
113
+ "tabs": self.get_formatted_tabs(request, obj),
114
+ "tabbed_admin_base_template": context.get("tabbed_admin_base_template", self.tabbed_admin_base_template),
115
+ }
116
+ return super().render_change_form(
134
117
  request,
135
- object_id,
118
+ context,
119
+ add=add,
120
+ change=change,
136
121
  form_url=form_url,
137
- extra_context=extra_context,
122
+ obj=obj,
138
123
  )
139
124
 
140
125
  class Media: