django-unfold 0.49.1__py3-none-any.whl → 0.51.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_unfold-0.51.0.dist-info/METADATA +81 -0
- {django_unfold-0.49.1.dist-info → django_unfold-0.51.0.dist-info}/RECORD +34 -30
- {django_unfold-0.49.1.dist-info → django_unfold-0.51.0.dist-info}/WHEEL +1 -1
- unfold/admin.py +4 -0
- unfold/contrib/filters/admin/dropdown_filters.py +1 -0
- unfold/contrib/filters/admin/mixins.py +10 -4
- unfold/contrib/filters/forms.py +2 -2
- unfold/dataclasses.py +3 -0
- unfold/decorators.py +8 -0
- unfold/enums.py +10 -0
- unfold/mixins/action_model_admin.py +4 -0
- unfold/sections.py +82 -0
- unfold/settings.py +1 -0
- unfold/sites.py +3 -0
- unfold/static/admin/js/inlines.js +18 -5
- unfold/static/unfold/css/styles.css +1 -1
- unfold/static/unfold/js/select2.init.js +29 -0
- unfold/styles.css +1 -1
- unfold/templates/admin/change_list.html +16 -16
- unfold/templates/admin/change_list_results.html +38 -40
- unfold/templates/admin/filter.html +2 -2
- unfold/templates/unfold/components/card.html +1 -1
- unfold/templates/unfold/components/table.html +42 -26
- unfold/templates/unfold/helpers/change_list_filter_actions.html +1 -1
- unfold/templates/unfold/helpers/empty_results.html +35 -0
- unfold/templates/unfold/helpers/tab_action.html +24 -19
- unfold/templates/unfold/helpers/tab_actions.html +19 -0
- unfold/templates/unfold/helpers/tab_items.html +47 -0
- unfold/templates/unfold/helpers/tab_list.html +3 -66
- unfold/templates/unfold/layouts/skeleton.html +1 -2
- unfold/templatetags/unfold.py +81 -2
- unfold/templatetags/unfold_list.py +10 -10
- unfold/views.py +14 -1
- django_unfold-0.49.1.dist-info/METADATA +0 -75
- unfold/contrib/filters/admin.py +0 -619
- {django_unfold-0.49.1.dist-info → django_unfold-0.51.0.dist-info}/LICENSE.md +0 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
Metadata-Version: 2.3
|
2
|
+
Name: django-unfold
|
3
|
+
Version: 0.51.0
|
4
|
+
Summary: Modern Django admin theme for seamless interface development
|
5
|
+
License: MIT
|
6
|
+
Keywords: django,admin,tailwind,theme
|
7
|
+
Requires-Python: >=3.9
|
8
|
+
Classifier: Environment :: Web Environment
|
9
|
+
Classifier: Framework :: Django
|
10
|
+
Classifier: Intended Audience :: Developers
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
12
|
+
Classifier: Operating System :: OS Independent
|
13
|
+
Classifier: Programming Language :: Python
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
20
|
+
Requires-Dist: django (>=4.2)
|
21
|
+
Project-URL: Homepage, https://unfoldadmin.com
|
22
|
+
Project-URL: Repository, https://github.com/unfoldadmin/django-unfold
|
23
|
+
Description-Content-Type: text/markdown
|
24
|
+
|
25
|
+

|
26
|
+
|
27
|
+
## Unfold Django Admin Theme
|
28
|
+
|
29
|
+
[](https://pypi.org/project/django-unfold/)
|
30
|
+
[](https://github.com/unfoldadmin/django-unfold/actions?query=workflow%3Arelease)
|
31
|
+

|
32
|
+

|
33
|
+
|
34
|
+
Transform your Django admin into a powerful, modern administrative interface with Unfold. This open-source theme enhances Django's default admin with beautiful design, advanced features, and developer-friendly customization options. Built on proven best practices, Unfold seamlessly integrates with your existing Django admin while providing all the tools needed to create sophisticated administrative areas that both developers and end-users will love.
|
35
|
+
|
36
|
+
- **Documentation:** The full documentation is available at [unfoldadmin.com](https://unfoldadmin.com?utm_medium=github&utm_source=unfold).
|
37
|
+
- **Unfold:** The demo site is available at [unfoldadmin.com](https://unfoldadmin.com?utm_medium=github&utm_source=unfold).
|
38
|
+
- **Formula:** A repository with a demo implementation is available at [github.com/unfoldadmin/formula](https://github.com/unfoldadmin/formula?utm_medium=github&utm_source=unfold).
|
39
|
+
- **Turbo:** A Django & Next.js boilerplate implementing Unfold is available at [github.com/unfoldadmin/turbo](https://github.com/unfoldadmin/turbo?utm_medium=github&utm_source=unfold).
|
40
|
+
- **Discord:** Join our Unfold community on [Discord](https://discord.gg/9sQj9MEbNz).
|
41
|
+
|
42
|
+
## Django & Unfold Development Services
|
43
|
+
|
44
|
+
Need assistance with implementing Unfold or require custom Django development? Professional consulting and development services are available to help transform your Django admin interface and enhance your web applications. Whether migrating from the native Django admin to Unfold or seeking expert technical guidance, reach out to discuss your project requirements and explore development possibilities. [Get in touch](https://unfoldadmin.com/consulting?utm_medium=github&utm_source=unfold) to learn more about available services.
|
45
|
+
|
46
|
+
## Fresh Features & Enhancements
|
47
|
+
|
48
|
+
- **Autocomplete filters:** Enhance filter functionality with built-in autocomplete support
|
49
|
+
- **Site dropdown:** Configurable dropdown menu in the header area for managing custom navigation links
|
50
|
+
- **Dropdown actions:** Organize action items in customizable dropdown menus
|
51
|
+
- **Custom tab navigation:** Create flexible, structured tab navigation with customizable routing
|
52
|
+
|
53
|
+
|
54
|
+
## Core Features & Capabilities
|
55
|
+
|
56
|
+
- **Visual Interface**: Provides a modern user interface based on the Tailwind CSS framework.
|
57
|
+
- **Sidebar Navigation**: Simplifies the creation of sidebar menus with icons, collapsible sections, and more.
|
58
|
+
- **Dark Mode Support**: Includes both light and dark mode themes.
|
59
|
+
- **Flexible Actions**: Provides multiple ways to define actions throughout the admin interface.
|
60
|
+
- **Advanced Filters**: Features custom dropdowns, autocomplete, numeric, datetime, and text field filters.
|
61
|
+
- **Dashboard Tools**: Includes helpers for building custom dashboard pages.
|
62
|
+
- **UI Components**: Offers reusable interface components such as cards, buttons, and charts.
|
63
|
+
- **WYSIWYG Editor**: Built-in support for WYSIWYG editing through Trix.
|
64
|
+
- **Array widget:** Built-in widget for `django.contrib.postgres.fields.ArrayField`
|
65
|
+
- **Inline tabs:** Group inlines into tab navigation in the change form
|
66
|
+
- **Model tabs:** Allow defining custom tab navigation for models
|
67
|
+
- **Fieldset tabs:** Merge multiple fieldsets into tabs in the change form
|
68
|
+
- **Sortable inlines:** Allow sorting inlines by dragging and dropping
|
69
|
+
- **Environment label:** Distinguish between environments by displaying a label
|
70
|
+
- **Nonrelated inlines:** Display nonrelated models as inlines in the change form
|
71
|
+
- **Favicons:** Built-in support for configuring various site favicons
|
72
|
+
- **Themes:** Allow customization of color scheme, background color, border radius, and more
|
73
|
+
- **Font colors:** Adjust font colors for better readability
|
74
|
+
- **Changeform modes:** Display fields in compressed mode in the change form
|
75
|
+
- **Language switcher:** Allow changing language directly from the admin area
|
76
|
+
- **Parallel admin:** Supports [running the default admin](https://unfoldadmin.com/blog/migrating-django-admin-unfold/?utm_medium=github&utm_source=unfold) alongside Unfold.
|
77
|
+
- **Third-party packages:** Provides default support for multiple popular applications.
|
78
|
+
- **Configuration:** Allows basic options to be changed in `settings.py`.
|
79
|
+
- **Dependencies:** Built entirely on `django.contrib.admin`.
|
80
|
+
- **VS Code:** Project configuration and development container included.
|
81
|
+
|
@@ -1,5 +1,5 @@
|
|
1
1
|
unfold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
unfold/admin.py,sha256=
|
2
|
+
unfold/admin.py,sha256=_dshyJ1LhGZhcx-eRdny9l1OEcIrqxmKzQzpfZcQAY4,6205
|
3
3
|
unfold/apps.py,sha256=SlBXPYrUd2uXn67qFbRvbXSUk3XFWrF4-5WELgDCvho,381
|
4
4
|
unfold/checks.py,sha256=8I3i4xR_KgyJdpQyZUZzKNeyYf-sNzg6PAlsREuMfgI,1664
|
5
5
|
unfold/components.py,sha256=vqkQzseYUvLXDohmTVAlbKopALjyX4WA9yglvdfhqu4,1283
|
@@ -8,13 +8,12 @@ unfold/contrib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
8
8
|
unfold/contrib/filters/admin/__init__.py,sha256=2pyv21jMqQVC8pnP8FOERHRH2hgZSOLQzV0BUn5wjHo,1216
|
9
9
|
unfold/contrib/filters/admin/autocomplete_filters.py,sha256=Jh3m3iQ8YubZRQDVzHPGfpk9RulOhHkZc0N7L6KV9wc,514
|
10
10
|
unfold/contrib/filters/admin/datetime_filters.py,sha256=cVari_7jsfeYxJoRBhcAUOr6v9XdtDtMuMs-S1Irafo,7757
|
11
|
-
unfold/contrib/filters/admin/dropdown_filters.py,sha256=
|
12
|
-
unfold/contrib/filters/admin/mixins.py,sha256=
|
11
|
+
unfold/contrib/filters/admin/dropdown_filters.py,sha256=YiPLakTIzLuojULfpctFV0aP8DwfWLDnU-lcjoK2qnE,3354
|
12
|
+
unfold/contrib/filters/admin/mixins.py,sha256=djaM5kxQFvl64GkNnhbCyo78UVNhDb0CIDiSNUXkUGo,4943
|
13
13
|
unfold/contrib/filters/admin/numeric_filters.py,sha256=8GNmesgMmMIfEZb2IrGbaBoJuvB2FpIc7wPIPBpHat4,6420
|
14
14
|
unfold/contrib/filters/admin/text_filters.py,sha256=NXyKm0Ed24N9pNfR7Dys5kTpZ_V5FUurdxk7KDMdRIg,2084
|
15
|
-
unfold/contrib/filters/admin.py,sha256=TvgtP5PZVMD9JJ22YdjC1CyH0Q9oxZON5zVXq2yGZVU,21127
|
16
15
|
unfold/contrib/filters/apps.py,sha256=wEySJy0gMLzFLb9XNKE-RexiO05X7NaQ5QmxZyziJ_k,136
|
17
|
-
unfold/contrib/filters/forms.py,sha256=
|
16
|
+
unfold/contrib/filters/forms.py,sha256=_eHiUaTKltkZ3pWG77LiWYnEVMC-2A-wj1LMLkcCPvc,7233
|
18
17
|
unfold/contrib/filters/static/unfold/filters/css/nouislider.min.css,sha256=rddL_jOGGVEY6wR-aw0VYovAfz5fPeAIsulrlSNb1hc,4221
|
19
18
|
unfold/contrib/filters/static/unfold/filters/js/DateTimeShortcuts.js,sha256=jgFNBDf6aHvUlyv0LEDHggXO-xA8pWOCWFWcVupdA30,19332
|
20
19
|
unfold/contrib/filters/static/unfold/filters/js/admin-numeric-filter.js,sha256=nTkiiJk4Abn9d6KigxPSEsereFhFq-v5n_boiiY1eII,1668
|
@@ -72,21 +71,23 @@ unfold/contrib/simple_history/templates/simple_history/object_history.html,sha25
|
|
72
71
|
unfold/contrib/simple_history/templates/simple_history/object_history_form.html,sha256=JKCe-QTBZMB2ol5LPiX3gNuNxFpi_rqlXC9X92PFBPE,2296
|
73
72
|
unfold/contrib/simple_history/templates/simple_history/object_history_list.html,sha256=ls_xEAAgGzbu0IXdjZk7scEyEJx0S7i3Khr9ND98gzY,6842
|
74
73
|
unfold/contrib/simple_history/templates/simple_history/submit_line.html,sha256=y8BleGHPNztA_R37rTB-zjJ68uDbE8flYSvMD0Jfl5Y,1734
|
75
|
-
unfold/dataclasses.py,sha256=
|
76
|
-
unfold/decorators.py,sha256=
|
74
|
+
unfold/dataclasses.py,sha256=a-9INnkCAIcnMgoffTcB1rxWCJH33AjhMCWIGWnjWbI,719
|
75
|
+
unfold/decorators.py,sha256=BZC6wr04lIBbK-0zylWxzgMqFWAw8slDaC4ccN8AqJI,3975
|
76
|
+
unfold/enums.py,sha256=9sTfyEycMWeoGPBa-ft6ZhQGnW1vkFg108RMBVf9nko,187
|
77
77
|
unfold/exceptions.py,sha256=gcCj1ox61E137bk_0Cqy4YC3SttdPgB-fiJUqpmyHSE,43
|
78
78
|
unfold/fields.py,sha256=J3goIMlP_XOmQ85Xgh2v5MylXSP1o5I7o9_So2FQn2k,7461
|
79
79
|
unfold/forms.py,sha256=BKv7eCbv29eCIuf1d_ZBmD4-_OIIzRaopiFd2nKbXNY,4520
|
80
80
|
unfold/mixins/__init__.py,sha256=YlhoDs9Y_DXQ8Ejr3enxuHMS1-Ij9fwukxNwpeOS4Co,190
|
81
|
-
unfold/mixins/action_model_admin.py,sha256=
|
81
|
+
unfold/mixins/action_model_admin.py,sha256=BPajuTGf7zAaZOqIq4shX8VQ3NTxWQpedvG58fmCTjk,12036
|
82
82
|
unfold/mixins/base_model_admin.py,sha256=PR4eqU48yB4CNy9Bjd7fjxbOFiFpZM4etYmBOSaRX_M,4140
|
83
83
|
unfold/overrides.py,sha256=ERVY9boZiXgjDYcTEZcIp7KWoeBZ45VM_zN31yAOjyQ,2922
|
84
|
-
unfold/
|
85
|
-
unfold/
|
84
|
+
unfold/sections.py,sha256=Lcg3xCZ76fqjm4vD4x7YdE5VsbTKluL-sX5QTEBlHxA,2379
|
85
|
+
unfold/settings.py,sha256=3ICha2I0oSaHhajG8159nHdNTYJInBtRQq9VziWKYKs,2709
|
86
|
+
unfold/sites.py,sha256=Pl8voDdMH_9RV1n3XmSz84T6OE8yDUAqNwlr-kPH1n8,16179
|
86
87
|
unfold/static/admin/js/admin/RelatedObjectLookups.js,sha256=alI0-yq7YPDJJJn-yg1ce79-Cv88yQDUrfaGqFZnsaY,9048
|
87
|
-
unfold/static/admin/js/inlines.js,sha256=
|
88
|
+
unfold/static/admin/js/inlines.js,sha256=74QODSKEkpKse4bft4wIFZquROcr2-hVTt9CEWOIJak,15061
|
88
89
|
unfold/static/unfold/css/simplebar.css,sha256=5LLaEM11pKi6JFCOLt4XKuZxTpT9rpdq_tNlaQytFlU,4647
|
89
|
-
unfold/static/unfold/css/styles.css,sha256=
|
90
|
+
unfold/static/unfold/css/styles.css,sha256=iMPVdCjI66jaAgjmHRV6n0jV8ssKCYa-v72mfbRlmo0,159966
|
90
91
|
unfold/static/unfold/fonts/inter/Inter-Bold.woff2,sha256=-oiBJ7baAVtlVp8DUfO1w5GtkokElR8cIOn4RiqNleo,114840
|
91
92
|
unfold/static/unfold/fonts/inter/Inter-Medium.woff2,sha256=D_PpRhThST61VjFP0keubEqFp3g7TMhr5TmUDPg_Kkg,114348
|
92
93
|
unfold/static/unfold/fonts/inter/Inter-Regular.woff2,sha256=4G9rG8VTqupORmgCPtCrChRxKcMQf1Ebx9A9NhsK4IU,111268
|
@@ -102,9 +103,9 @@ unfold/static/unfold/js/alpine.sort.js,sha256=q6LxgConwu8M8R03mZSBcsKwJv6fF7oomP
|
|
102
103
|
unfold/static/unfold/js/app.js,sha256=mxCSV8gZvRLHab-_Xm_229NtQ9IX-59vS_GKWTp9liM,7748
|
103
104
|
unfold/static/unfold/js/chart.js,sha256=22W6cFERR-CElMOKRgMMicueMVP0Vf7FBEBYH8Z8tCk,200633
|
104
105
|
unfold/static/unfold/js/htmx.js,sha256=acrv0NqSJpBm5yXX_hdeJrnVDJYuMFZFnAxHcVTNudM,50918
|
105
|
-
unfold/static/unfold/js/select2.init.js,sha256=
|
106
|
+
unfold/static/unfold/js/select2.init.js,sha256=gXZngZh-l5ID2-VmndpGseNi6A0zKB18UgPyCor68CU,1040
|
106
107
|
unfold/static/unfold/js/simplebar.js,sha256=t-uG1FAD6ZoiMeN--wac0XRS7SxoDVG6zvRnGuEp7X8,27176
|
107
|
-
unfold/styles.css,sha256=
|
108
|
+
unfold/styles.css,sha256=yp_oUco8yAJa-lJiioMAoORC-JGCMHFrhRjuk1aEYog,18786
|
108
109
|
unfold/templates/admin/actions.html,sha256=aroIid16mORcx-0p8O2dOoWupEoTGX66pt-PAXjSYZ0,3063
|
109
110
|
unfold/templates/admin/app_index.html,sha256=GSBry97gDcK3scTP-Fs4FXcSItRxxE87Wv4sDtMTlbc,1244
|
110
111
|
unfold/templates/admin/app_list.html,sha256=VtntgHpbZdXbt_HXBLAtbuMdz1alS7F_S7eG37M5Rig,2855
|
@@ -114,15 +115,15 @@ unfold/templates/admin/base.html,sha256=3xQmoD_7cu2UlgEdvnt7v_CibT9t1Iul0b-VU2Aw
|
|
114
115
|
unfold/templates/admin/base_site.html,sha256=UOsecaCycpyn_ygJNIKO7MQtDFJuHv--r83-mzaVY30,300
|
115
116
|
unfold/templates/admin/change_form.html,sha256=LfeAeLYpJvNhOMJWQFeb9oSrAznlB4pnFrqTVMCIy4o,5340
|
116
117
|
unfold/templates/admin/change_form_object_tools.html,sha256=eyeH-i2HgEM0Yi-OJA2D1VnKJyC19A_my1IDGxxoP8Y,593
|
117
|
-
unfold/templates/admin/change_list.html,sha256=
|
118
|
+
unfold/templates/admin/change_list.html,sha256=AhGUdt-S3m30WhSraWnBdLwZQ1JU9yZeVDL0WDqCEMI,5164
|
118
119
|
unfold/templates/admin/change_list_object_tools.html,sha256=cmMiT2nT20Ph5yfpj9aHPr76Z-JP4aSXp0o-Rnad28s,147
|
119
|
-
unfold/templates/admin/change_list_results.html,sha256=
|
120
|
+
unfold/templates/admin/change_list_results.html,sha256=n64K5ocS62kujxzzkojzOx4jJuiYcO8r4mcJfcsCQAs,7931
|
120
121
|
unfold/templates/admin/date_hierarchy.html,sha256=Jl_Vk05fXvsSvod5Dw2p3KhpCQGjtSX1zqlNjjkBFR4,1411
|
121
122
|
unfold/templates/admin/delete_confirmation.html,sha256=yT_NHbFHZEjkSCaGVcM52GCG-FDmWiJdTFLbq9CBCx4,4619
|
122
123
|
unfold/templates/admin/delete_selected_confirmation.html,sha256=QR0JhrPR8YI8KpQnB3xyrKxaui-_pEQmfaMDbcXjjZ0,4391
|
123
124
|
unfold/templates/admin/edit_inline/stacked.html,sha256=-ASy7Jd0SwWBDxurucbus86YT2AokJEcCUrqPlHVDQA,7644
|
124
125
|
unfold/templates/admin/edit_inline/tabular.html,sha256=FBgzUb-U0cZCN28-cpHzRSyPE6bgseD_r3MY1AP0nGQ,2813
|
125
|
-
unfold/templates/admin/filter.html,sha256=
|
126
|
+
unfold/templates/admin/filter.html,sha256=0B_hpLybHw1wUPPCN3KJvoWrx03iFeqP8m1LRCjnLlQ,2012
|
126
127
|
unfold/templates/admin/includes/fieldset.html,sha256=gX-dc-jPLswk21XSKUXzAU8WFl3CFfeVrIAU2bviPyg,812
|
127
128
|
unfold/templates/admin/includes/object_delete_summary.html,sha256=FgwfapZCKWtnFtTHqh1MRuxxLot4bAw92WCcR_V8ImI,444
|
128
129
|
unfold/templates/admin/index.html,sha256=JnNDpNKqFKVKMQvpUQo6ddcFqGadK5g78pxpKAHLuMU,583
|
@@ -137,7 +138,7 @@ unfold/templates/registration/logged_out.html,sha256=GgLzqmOGpiw5FcA-Aw_T6YvhYHh
|
|
137
138
|
unfold/templates/registration/password_change_done.html,sha256=9HDpSraz3Kxdy0Fghbn-Lv0GAtpPgG6cuO7fvfMiYg8,1077
|
138
139
|
unfold/templates/registration/password_change_form.html,sha256=EgakVWzpQUEJKQS0AOfk8O_CY1bKbyWXSUuBaxtQEdU,2232
|
139
140
|
unfold/templates/unfold/components/button.html,sha256=TABo79ppuGlm2ENvRs6L3Vne8B5_9he_OhZTnPMiitQ,473
|
140
|
-
unfold/templates/unfold/components/card.html,sha256=
|
141
|
+
unfold/templates/unfold/components/card.html,sha256=FVLN7kQZqMd_uhEi1LpiN9FUxZCa4RgGHYGmofCtQro,1141
|
141
142
|
unfold/templates/unfold/components/chart/bar.html,sha256=nDdDCUXvFd793OpNgNPQo0vBmvYngMsQyPHVTf1vfOw,297
|
142
143
|
unfold/templates/unfold/components/chart/cohort.html,sha256=elZj9e9E9cfVey_9LSOaDoVSE3Wn3BagSrwIXRSFadM,2354
|
143
144
|
unfold/templates/unfold/components/chart/line.html,sha256=DHaZUFTlCs5cX7ioYdTzoN4ITHWNcEoNSUp7v3hlo_E,298
|
@@ -147,7 +148,7 @@ unfold/templates/unfold/components/icon.html,sha256=Qlhcf41FOwNVJ-nvA0RJ_Dn6JW6P
|
|
147
148
|
unfold/templates/unfold/components/navigation.html,sha256=NCPFXM1Q__2LoIyNNYbhhZZPtdw3eLvmc9vlhnm9mhg,887
|
148
149
|
unfold/templates/unfold/components/progress.html,sha256=BnH2uC_ZL5ITvMjHiHoM0gjtbRTLNU1-tFcfCuJO0BE,808
|
149
150
|
unfold/templates/unfold/components/separator.html,sha256=yvHywT_MFkx5dNC2K53OFHRGxLDsEjRpptujXyGeoTY,168
|
150
|
-
unfold/templates/unfold/components/table.html,sha256=
|
151
|
+
unfold/templates/unfold/components/table.html,sha256=awXLt0diLeUAk1akVvyXiNApExtENR-MP-lf4MQrWTs,3075
|
151
152
|
unfold/templates/unfold/components/text.html,sha256=-GjxvdiaBQIaNfPSzT6SSIwnc3R27FkSDQMoF3FDPso,102
|
152
153
|
unfold/templates/unfold/components/title.html,sha256=aMYSO30ybFYqPnqwlJVh2uNmcgnVrRycZkHTjJTjpX8,171
|
153
154
|
unfold/templates/unfold/components/tracker.html,sha256=-PvDHdAAB2G5mKXpQUtljWJYhhavsa1aEoBvLrCiCJo,284
|
@@ -161,7 +162,7 @@ unfold/templates/unfold/helpers/boolean.html,sha256=kcSZr3siQeBWIy_jsx1tFf4m6IB3
|
|
161
162
|
unfold/templates/unfold/helpers/breadcrumb_item.html,sha256=9T6ojN7LOXIlgwSwlIwHgy5U22eQYtarCqcmzsQIoPU,201
|
162
163
|
unfold/templates/unfold/helpers/change_list_actions.html,sha256=p1_vC2Q_Fb-gAHA8y1zzOXqqn5TPQMrQfE26PkOY_ok,656
|
163
164
|
unfold/templates/unfold/helpers/change_list_filter.html,sha256=0l-c4H2PcDkAuzI6asAJf2rBfYavYG62F9d7yWWdkSI,1852
|
164
|
-
unfold/templates/unfold/helpers/change_list_filter_actions.html,sha256=
|
165
|
+
unfold/templates/unfold/helpers/change_list_filter_actions.html,sha256=fTlM6jyS83FhGulFYuhFVLJOGHRJV3mFCWDQnp1kp0U,1760
|
165
166
|
unfold/templates/unfold/helpers/delete_submit_line.html,sha256=N1w_TDIDN7Spj5diuhRUVOVgz2TiSeHVK2QvBjTLv2w,665
|
166
167
|
unfold/templates/unfold/helpers/display_header.html,sha256=rhru2GSxR0mH8_FEQuQVIS8gGGjaiWMV9f2HCPGMsaQ,1698
|
167
168
|
unfold/templates/unfold/helpers/display_label.html,sha256=LS9DWzYjHkYLV27sZDwyXlg2sLJ0AlId9FbjnXpsbfg,317
|
@@ -171,6 +172,7 @@ unfold/templates/unfold/helpers/edit_inline/tabular_field.html,sha256=BRCAXdv-HB
|
|
171
172
|
unfold/templates/unfold/helpers/edit_inline/tabular_heading.html,sha256=ER8R64wnKOu26WTwP4_Wxt-LRB_zRkXLhheZ_utVvKY,1523
|
172
173
|
unfold/templates/unfold/helpers/edit_inline/tabular_row.html,sha256=Cfs2m5eh3mLcMgL0_dSAokAscgq4q19KsnUPZECmDgw,2013
|
173
174
|
unfold/templates/unfold/helpers/edit_inline/tabular_title.html,sha256=JPSue6mD1-KZ3tiymbRrv1G2XgsSim4cT_6HhzYJaYY,2710
|
175
|
+
unfold/templates/unfold/helpers/empty_results.html,sha256=KV9DLKLURDtlkjDI88u05l6cXiOoeSv1nR4wFNIQ2hE,1933
|
174
176
|
unfold/templates/unfold/helpers/field.html,sha256=Ds-zUHkdyxamfUCVNhxvtM0XoJg9OCA0QcsLbLWv4oo,882
|
175
177
|
unfold/templates/unfold/helpers/field_readonly.html,sha256=4qtXjWE7SA2qZSTYLOv0lT4pQfD0TE34mvWQJY7jhS8,237
|
176
178
|
unfold/templates/unfold/helpers/field_readonly_value.html,sha256=6DNteF8x6_tihQZVCGgz2CqB0ogsLRJhxgDep0sHguc,464
|
@@ -204,14 +206,16 @@ unfold/templates/unfold/helpers/site_dropdown.html,sha256=Zwg5ZGVIEHAI2h-YcWDDBz
|
|
204
206
|
unfold/templates/unfold/helpers/site_icon.html,sha256=rB6oc6VBB0T7wtyGOPcrq6qepDRaA54F6-Wxtaru-ks,1297
|
205
207
|
unfold/templates/unfold/helpers/site_logo.html,sha256=S_QJoT2qh0xw0ciaKxoT4GJ6QIH5eqgRSC0abbWWkOI,423
|
206
208
|
unfold/templates/unfold/helpers/submit.html,sha256=4Mgf4lx7Atm8GPqD6LTJK3NA9zoSJjs9VPig7sDp8Ao,203
|
207
|
-
unfold/templates/unfold/helpers/tab_action.html,sha256=
|
208
|
-
unfold/templates/unfold/helpers/
|
209
|
+
unfold/templates/unfold/helpers/tab_action.html,sha256=6N6Xi7XGtweS6gt0oZrVu6AIaJ9WIQSH-mpndn0CCYE,2263
|
210
|
+
unfold/templates/unfold/helpers/tab_actions.html,sha256=DMNqY1YyrNrcutOMC3J1neZZjIkPeYShp1i5xZ10nrc,695
|
211
|
+
unfold/templates/unfold/helpers/tab_items.html,sha256=Gi6cjYJ7tJWO6zSXjg8xNHY9ALpYzjQOEORusf_AZfg,3325
|
212
|
+
unfold/templates/unfold/helpers/tab_list.html,sha256=Tqkug9GyoIQ2geVKWrnnuE0bxeTRXj0MSEwwixoOGz4,436
|
209
213
|
unfold/templates/unfold/helpers/theme_switch.html,sha256=Kh3Q8RuBWCUuY8YJLwBwd5yKzDhK6y0Ggx_ERoGEGv8,2218
|
210
214
|
unfold/templates/unfold/helpers/userlinks.html,sha256=oZqiwCxG_zRecAbzYrr8_hQvkndVB6-liP6LEZM1UZc,863
|
211
215
|
unfold/templates/unfold/helpers/welcomemsg.html,sha256=a7VjZ8J1mn-DAo57nhUP096SEcBOqcCWrWt2qoT0cyg,1882
|
212
216
|
unfold/templates/unfold/layouts/base.html,sha256=e9T-vuPvrySHf23LLwRuTQXUg0Q4x-6gmT_yXghqc-I,278
|
213
217
|
unfold/templates/unfold/layouts/base_simple.html,sha256=VigjNWnWOt_XtbahvqsroPf8mdwl7cDGbg5fEaLmG9s,1211
|
214
|
-
unfold/templates/unfold/layouts/skeleton.html,sha256=
|
218
|
+
unfold/templates/unfold/layouts/skeleton.html,sha256=TmZ0hX5j7McwSiYcdGGuhAjDunPDCWtPC7lDF6hbtDk,4641
|
215
219
|
unfold/templates/unfold/templatetags/preserve_changelist_filters.html,sha256=sx2jUhogNY4emBhY8PqxQ6mXifbXQb_IQI9Hd0boJI0,111
|
216
220
|
unfold/templates/unfold/widgets/clearable_file_input.html,sha256=4vsLRjqOmGqdU4aPSq81rc-mdRvpBr-H_bC5ScyUkEY,2231
|
217
221
|
unfold/templates/unfold/widgets/clearable_file_input_small.html,sha256=NNlosUwhzv-3SZH9LdliL5c6fdoVNRb1JP0uHwFV-N8,2849
|
@@ -229,13 +233,13 @@ unfold/templates/unfold/widgets/textarea_expandable.html,sha256=Pqi2udY0FWxVA-B1
|
|
229
233
|
unfold/templates/unfold/widgets/time.html,sha256=WXo2LG1v_gBZBSg-zocj7oujMKI0MWLYCIFfB04HMLQ,122
|
230
234
|
unfold/templates/unfold/widgets/url.html,sha256=IRLgW44VTKN7UrSWeywJwaxQhfG5jhhXuT-KTadKX58,304
|
231
235
|
unfold/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
232
|
-
unfold/templatetags/unfold.py,sha256=
|
233
|
-
unfold/templatetags/unfold_list.py,sha256
|
236
|
+
unfold/templatetags/unfold.py,sha256=dx-_6ml3Lt6AGYdl4TnDFFssLrqK0LwlcrKERlfV_GI,14462
|
237
|
+
unfold/templatetags/unfold_list.py,sha256=DTPVSM2gD59-R4bk39VOEqtzctCB2vgxOINuzHzZIho,14108
|
234
238
|
unfold/typing.py,sha256=i7LM2LiwYTAjT5-OLDUPVn5b9X-DMmHnjlZG2toWwSE,692
|
235
239
|
unfold/utils.py,sha256=L0oC9-j1B__BZ21M7i6rTXNbzCQaZ4T0qHYQcNupk0A,5480
|
236
|
-
unfold/views.py,sha256=
|
240
|
+
unfold/views.py,sha256=FuYnMrlg6SegLUDDN6An__yZj8rchD_iBK8myieYhkA,1492
|
237
241
|
unfold/widgets.py,sha256=esW1wxdbZwUhF31ensitBF8_6kVq_Gp0_iDgv6F5Rr0,20246
|
238
|
-
django_unfold-0.
|
239
|
-
django_unfold-0.
|
240
|
-
django_unfold-0.
|
241
|
-
django_unfold-0.
|
242
|
+
django_unfold-0.51.0.dist-info/LICENSE.md,sha256=Ltk_quRyyvV3J5v3brtOqmibeZSw2Hrb8bY1W3ya0Ik,1077
|
243
|
+
django_unfold-0.51.0.dist-info/METADATA,sha256=SsSBDtZp3pGZVgBR5aag-LRLeSrV4vmssqpekTiQ_ng,5929
|
244
|
+
django_unfold-0.51.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
245
|
+
django_unfold-0.51.0.dist-info/RECORD,,
|
unfold/admin.py
CHANGED
@@ -20,6 +20,7 @@ from unfold.forms import ActionForm
|
|
20
20
|
from unfold.mixins import ActionModelAdminMixin, BaseModelAdminMixin
|
21
21
|
from unfold.overrides import FORMFIELD_OVERRIDES_INLINE
|
22
22
|
from unfold.typing import FieldsetsType
|
23
|
+
from unfold.views import ChangeList
|
23
24
|
from unfold.widgets import UnfoldBooleanWidget
|
24
25
|
|
25
26
|
checkbox = UnfoldBooleanWidget(
|
@@ -168,6 +169,9 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
|
|
168
169
|
return redirect(request.GET["next"])
|
169
170
|
return res
|
170
171
|
|
172
|
+
def get_changelist(self, request, **kwargs):
|
173
|
+
return ChangeList
|
174
|
+
|
171
175
|
|
172
176
|
class TabularInline(BaseModelAdminMixin, BaseTabularInline):
|
173
177
|
formfield_overrides = FORMFIELD_OVERRIDES_INLINE
|
@@ -83,6 +83,7 @@ class RelatedDropdownFilter(ValueMixin, DropdownMixin, admin.RelatedFieldListFil
|
|
83
83
|
) -> None:
|
84
84
|
super().__init__(field, request, params, model, model_admin, field_path)
|
85
85
|
self.model_admin = model_admin
|
86
|
+
self.request = request
|
86
87
|
|
87
88
|
def choices(self, changelist: ChangeList) -> Generator[dict[str, Any], None, None]:
|
88
89
|
yield {
|
@@ -4,10 +4,12 @@ from typing import Any, Optional
|
|
4
4
|
from django.contrib.admin.views.main import ChangeList
|
5
5
|
from django.core.validators import EMPTY_VALUES
|
6
6
|
from django.db.models import QuerySet
|
7
|
+
from django.db.models.fields import BLANK_CHOICE_DASH, Field
|
7
8
|
from django.forms import ValidationError
|
8
9
|
from django.http import HttpRequest
|
9
10
|
from django.utils.translation import gettext_lazy as _
|
10
11
|
|
12
|
+
from unfold.admin import ModelAdmin
|
11
13
|
from unfold.contrib.filters.forms import (
|
12
14
|
AutocompleteDropdownForm,
|
13
15
|
DropdownForm,
|
@@ -123,11 +125,15 @@ class RangeNumericMixin:
|
|
123
125
|
|
124
126
|
|
125
127
|
class AutocompleteMixin:
|
126
|
-
def
|
127
|
-
|
128
|
+
def has_output(self) -> bool:
|
129
|
+
return True
|
128
130
|
|
129
|
-
|
130
|
-
|
131
|
+
def field_choices(
|
132
|
+
self, field: Field, request: HttpRequest, model_admin: ModelAdmin
|
133
|
+
) -> list[tuple[str, str]]:
|
134
|
+
return [
|
135
|
+
("", BLANK_CHOICE_DASH),
|
136
|
+
]
|
131
137
|
|
132
138
|
def choices(
|
133
139
|
self, changelist: ChangeList
|
unfold/contrib/filters/forms.py
CHANGED
@@ -52,7 +52,7 @@ class AutocompleteDropdownForm(forms.Form):
|
|
52
52
|
self.fields[name] = self.field(
|
53
53
|
label=label,
|
54
54
|
required=False,
|
55
|
-
queryset=field.remote_field.model.objects
|
55
|
+
queryset=field.remote_field.model.objects,
|
56
56
|
widget=self.widget(field, model_admin.admin_site),
|
57
57
|
)
|
58
58
|
|
@@ -61,7 +61,7 @@ class AutocompleteDropdownForm(forms.Form):
|
|
61
61
|
"admin/js/vendor/jquery/jquery.js",
|
62
62
|
"admin/js/vendor/select2/select2.full.js",
|
63
63
|
"admin/js/jquery.init.js",
|
64
|
-
"
|
64
|
+
"unfold/js/select2.init.js",
|
65
65
|
)
|
66
66
|
css = {
|
67
67
|
"screen": (
|
unfold/dataclasses.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
2
|
from typing import Callable, Optional, Union
|
3
3
|
|
4
|
+
from unfold.enums import ActionVariant
|
5
|
+
|
4
6
|
from .typing import ActionFunction
|
5
7
|
|
6
8
|
|
@@ -13,6 +15,7 @@ class UnfoldAction:
|
|
13
15
|
attrs: Optional[dict] = None
|
14
16
|
object_id: Optional[Union[int, str]] = None
|
15
17
|
icon: Optional[str] = None
|
18
|
+
variant: Optional[ActionVariant] = ActionVariant.DEFAULT
|
16
19
|
|
17
20
|
|
18
21
|
@dataclass
|
unfold/decorators.py
CHANGED
@@ -7,6 +7,8 @@ from django.db.models import Model
|
|
7
7
|
from django.db.models.expressions import BaseExpression, Combinable
|
8
8
|
from django.http import HttpRequest, HttpResponse
|
9
9
|
|
10
|
+
from unfold.enums import ActionVariant
|
11
|
+
|
10
12
|
from .typing import ActionFunction
|
11
13
|
|
12
14
|
|
@@ -18,6 +20,7 @@ def action(
|
|
18
20
|
url_path: Optional[str] = None,
|
19
21
|
attrs: Optional[dict[str, Any]] = None,
|
20
22
|
icon: Optional[str] = None,
|
23
|
+
variant: Optional[ActionVariant] = ActionVariant.DEFAULT,
|
21
24
|
) -> ActionFunction:
|
22
25
|
def decorator(func: Callable) -> ActionFunction:
|
23
26
|
def inner(
|
@@ -59,6 +62,11 @@ def action(
|
|
59
62
|
if icon is not None:
|
60
63
|
inner.icon = icon
|
61
64
|
|
65
|
+
if variant is not None:
|
66
|
+
inner.variant = variant
|
67
|
+
else:
|
68
|
+
inner.variant = ActionVariant.DEFAULT
|
69
|
+
|
62
70
|
inner.attrs = attrs or {}
|
63
71
|
return inner
|
64
72
|
|
unfold/enums.py
ADDED
@@ -7,6 +7,7 @@ from django.template.response import TemplateResponse
|
|
7
7
|
from django.urls import reverse
|
8
8
|
|
9
9
|
from unfold.dataclasses import UnfoldAction
|
10
|
+
from unfold.enums import ActionVariant
|
10
11
|
from unfold.exceptions import UnfoldException
|
11
12
|
|
12
13
|
|
@@ -119,6 +120,7 @@ class ActionModelAdminMixin:
|
|
119
120
|
path=getattr(method, "url_path", action),
|
120
121
|
attrs=method.attrs if hasattr(method, "attrs") else None,
|
121
122
|
icon=method.icon if hasattr(method, "icon") else None,
|
123
|
+
variant=method.variant if hasattr(method, "variant") else None,
|
122
124
|
)
|
123
125
|
|
124
126
|
def get_actions_list(self, request: HttpRequest) -> list[UnfoldAction]:
|
@@ -265,6 +267,7 @@ class ActionModelAdminMixin:
|
|
265
267
|
return {
|
266
268
|
"title": action.description,
|
267
269
|
"icon": action.icon,
|
270
|
+
"variant": action.variant,
|
268
271
|
"attrs": action.method.attrs,
|
269
272
|
"path": get_action_path(action),
|
270
273
|
}
|
@@ -276,6 +279,7 @@ class ActionModelAdminMixin:
|
|
276
279
|
dropdown = {
|
277
280
|
"title": nav_item["title"],
|
278
281
|
"icon": nav_item.get("icon"),
|
282
|
+
"variant": nav_item.get("variant", ActionVariant.DEFAULT),
|
279
283
|
"items": [],
|
280
284
|
}
|
281
285
|
|
unfold/sections.py
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
from django.contrib.admin.utils import label_for_field, lookup_field
|
2
|
+
from django.db.models import Model
|
3
|
+
from django.http import HttpRequest
|
4
|
+
from django.template.loader import render_to_string
|
5
|
+
|
6
|
+
from unfold.utils import display_for_field
|
7
|
+
|
8
|
+
|
9
|
+
class BaseSection:
|
10
|
+
def __init__(self, request: HttpRequest, instance: Model) -> None:
|
11
|
+
self.request = request
|
12
|
+
self.instance = instance
|
13
|
+
|
14
|
+
def render(self) -> str:
|
15
|
+
raise NotImplementedError(
|
16
|
+
"Section subclasses must implement the render method."
|
17
|
+
)
|
18
|
+
|
19
|
+
|
20
|
+
class TableSection(BaseSection):
|
21
|
+
fields = []
|
22
|
+
related_name = None
|
23
|
+
verbose_name = None
|
24
|
+
height = None
|
25
|
+
|
26
|
+
def render(self) -> str:
|
27
|
+
results = getattr(self.instance, self.related_name)
|
28
|
+
headers = []
|
29
|
+
rows = []
|
30
|
+
|
31
|
+
for field_name in self.fields:
|
32
|
+
if hasattr(self, field_name):
|
33
|
+
if hasattr(getattr(self, field_name), "short_description"):
|
34
|
+
headers.append(getattr(self, field_name).short_description)
|
35
|
+
else:
|
36
|
+
headers.append(field_name)
|
37
|
+
else:
|
38
|
+
headers.append(label_for_field(field_name, results.model))
|
39
|
+
|
40
|
+
for result in results.all():
|
41
|
+
row = []
|
42
|
+
|
43
|
+
for field_name in self.fields:
|
44
|
+
if hasattr(self, field_name):
|
45
|
+
row.append(getattr(self, field_name)(result))
|
46
|
+
else:
|
47
|
+
field, attr, value = lookup_field(field_name, result)
|
48
|
+
row.append(display_for_field(value, field, "-"))
|
49
|
+
|
50
|
+
rows.append(row)
|
51
|
+
|
52
|
+
context = {
|
53
|
+
"request": self.request,
|
54
|
+
"table": {
|
55
|
+
"headers": headers,
|
56
|
+
"rows": rows,
|
57
|
+
},
|
58
|
+
}
|
59
|
+
|
60
|
+
if hasattr(self, "verbose_name") and self.verbose_name:
|
61
|
+
context["title"] = self.verbose_name
|
62
|
+
|
63
|
+
if hasattr(self, "height") and self.height:
|
64
|
+
context["height"] = self.height
|
65
|
+
|
66
|
+
return render_to_string(
|
67
|
+
"unfold/components/table.html",
|
68
|
+
context=context,
|
69
|
+
)
|
70
|
+
|
71
|
+
|
72
|
+
class TemplateSection(BaseSection):
|
73
|
+
template_name = None
|
74
|
+
|
75
|
+
def render(self) -> str:
|
76
|
+
return render_to_string(
|
77
|
+
self.template_name,
|
78
|
+
context={
|
79
|
+
"request": self.request,
|
80
|
+
"instance": self.instance,
|
81
|
+
},
|
82
|
+
)
|
unfold/settings.py
CHANGED
unfold/sites.py
CHANGED
@@ -88,6 +88,9 @@ class UnfoldAdminSite(AdminSite):
|
|
88
88
|
"border_radius": self._get_config("BORDER_RADIUS", request),
|
89
89
|
"colors": self._get_colors("COLORS", request),
|
90
90
|
"environment": self._get_config("ENVIRONMENT", request),
|
91
|
+
"environment_title_prefix": self._get_config(
|
92
|
+
"ENVIRONMENT_TITLE_PREFIX", request
|
93
|
+
),
|
91
94
|
"tab_list": self.get_tabs_list(request),
|
92
95
|
"styles": self._get_list("STYLES", request),
|
93
96
|
"scripts": self._get_list("SCRIPTS", request),
|
@@ -225,11 +225,24 @@
|
|
225
225
|
}
|
226
226
|
};
|
227
227
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
.
|
232
|
-
|
228
|
+
// !CHANGED from original. Business logic for tabular inlines is different.
|
229
|
+
if ($this.parent().is("tbody")) {
|
230
|
+
$this
|
231
|
+
.parent()
|
232
|
+
.parent()
|
233
|
+
.find("tr.form-row")
|
234
|
+
.each(function (i) {
|
235
|
+
$(this)
|
236
|
+
.not("." + options.emptyCssClass)
|
237
|
+
.addClass(options.formCssClass);
|
238
|
+
});
|
239
|
+
} else {
|
240
|
+
$this.each(function (i) {
|
241
|
+
$(this)
|
242
|
+
.not("." + options.emptyCssClass)
|
243
|
+
.addClass(options.formCssClass);
|
244
|
+
});
|
245
|
+
}
|
233
246
|
|
234
247
|
// Create the delete buttons for all unsaved inlines:
|
235
248
|
$this
|