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.
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/MANIFEST.in +1 -0
- django_tabbed_admin3-3.2.0/PKG-INFO +233 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/README.rst +12 -0
- django_tabbed_admin3-3.2.0/django_tabbed_admin3.egg-info/PKG-INFO +233 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/django_tabbed_admin3.egg-info/SOURCES.txt +1 -11
- django_tabbed_admin3-3.2.0/django_tabbed_admin3.egg-info/top_level.txt +1 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/pyproject.toml +22 -6
- django_tabbed_admin3-3.2.0/setup.cfg +4 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/admin.py +20 -35
- django_tabbed_admin3-3.2.0/tabbed_admin/templates/tabbed_admin/change_form.html +65 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/templatetags/tabbed_admin_tags.py +13 -10
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/tests/admin.py +5 -15
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/tests/models.py +8 -16
- django_tabbed_admin3-3.2.0/tabbed_admin/tests/runtests.py +50 -0
- django_tabbed_admin3-3.2.0/tabbed_admin/tests/tests.py +193 -0
- django_tabbed_admin3-3.2.0/tabbed_admin/tests/urls.py +8 -0
- django_tabbed_admin3-3.1.0/PKG-INFO +0 -34
- django_tabbed_admin3-3.1.0/django_tabbed_admin3.egg-info/PKG-INFO +0 -34
- django_tabbed_admin3-3.1.0/django_tabbed_admin3.egg-info/top_level.txt +0 -2
- django_tabbed_admin3-3.1.0/setup.cfg +0 -7
- django_tabbed_admin3-3.1.0/setup.py +0 -38
- django_tabbed_admin3-3.1.0/tabbed_admin/templates/tabbed_admin/change_form.html +0 -111
- django_tabbed_admin3-3.1.0/tabbed_admin/tests/runtests.py +0 -74
- django_tabbed_admin3-3.1.0/tabbed_admin/tests/tests.py +0 -240
- django_tabbed_admin3-3.1.0/tabbed_admin/tests/urls.py +0 -6
- django_tabbed_admin3-3.1.0/tabbed_admin_exemple/manage.py +0 -10
- django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/__init__.py +0 -0
- django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/band/__init__.py +0 -0
- django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/band/admin.py +0 -51
- django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/band/models.py +0 -58
- django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/settings.py +0 -109
- django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/urls.py +0 -22
- django_tabbed_admin3-3.1.0/tabbed_admin_exemple/tabbed_admin_exemple/wsgi.py +0 -16
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/AUTHORS.txt +0 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/LICENSE.txt +0 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/django_tabbed_admin3.egg-info/dependency_links.txt +0 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/django_tabbed_admin3.egg-info/requires.txt +0 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/__init__.py +0 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/models.py +0 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/settings.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/tabbed_admin.css +0 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/static/tabbed_admin/css/tabbed_grappelli_admin.css +0 -0
- {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
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/templatetags/__init__.py +0 -0
- {django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/tabbed_admin/tests/__init__.py +0 -0
|
@@ -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
|
{django_tabbed_admin3-3.1.0 → django_tabbed_admin3-3.2.0}/django_tabbed_admin3.egg-info/SOURCES.txt
RENAMED
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tabbed_admin
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=
|
|
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.
|
|
8
|
-
description = "Easily add tabs to django admin forms. Django 6 compatible fork."
|
|
9
|
-
readme = "README.
|
|
10
|
-
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"]
|
|
@@ -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
|
|
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
|
|
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
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
118
|
+
context,
|
|
119
|
+
add=add,
|
|
120
|
+
change=change,
|
|
136
121
|
form_url=form_url,
|
|
137
|
-
|
|
122
|
+
obj=obj,
|
|
138
123
|
)
|
|
139
124
|
|
|
140
125
|
class Media:
|