django-unfold 0.24.0__py3-none-any.whl → 0.26.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.24.0.dist-info → django_unfold-0.26.0.dist-info}/METADATA +51 -6
- {django_unfold-0.24.0.dist-info → django_unfold-0.26.0.dist-info}/RECORD +36 -26
- unfold/admin.py +11 -3
- unfold/contrib/import_export/forms.py +28 -5
- unfold/contrib/import_export/templates/admin/import_export/change_form.html +10 -0
- unfold/contrib/import_export/templates/admin/import_export/export.html +38 -3
- unfold/contrib/import_export/templates/admin/import_export/import_form.html +9 -20
- unfold/contrib/import_export/templates/admin/import_export/resource_fields_list.html +24 -0
- unfold/contrib/inlines/__init__.py +0 -0
- unfold/contrib/inlines/admin.py +141 -0
- unfold/contrib/inlines/apps.py +6 -0
- unfold/contrib/inlines/checks.py +18 -0
- unfold/contrib/inlines/forms.py +43 -0
- unfold/forms.py +6 -0
- unfold/static/unfold/css/simplebar.css +230 -0
- unfold/static/unfold/css/styles.css +1 -1
- unfold/static/unfold/js/simplebar.js +10 -0
- unfold/styles.css +10 -2
- unfold/templates/admin/app_list.html +1 -1
- unfold/templates/admin/change_form.html +11 -9
- unfold/templates/admin/change_list_results.html +67 -65
- unfold/templates/admin/edit_inline/stacked.html +7 -7
- unfold/templates/admin/edit_inline/tabular.html +111 -109
- unfold/templates/admin/includes/fieldset.html +1 -1
- unfold/templates/unfold/helpers/app_list.html +1 -1
- unfold/templates/unfold/helpers/display_header.html +11 -8
- unfold/templates/unfold/helpers/field.html +20 -6
- unfold/templates/unfold/helpers/fieldsets_tabs.html +4 -4
- unfold/templates/unfold/helpers/form_label.html +1 -1
- unfold/templates/unfold/layouts/skeleton.html +2 -0
- unfold/templates/unfold/widgets/foreign_key_raw_id.html +21 -0
- unfold/templates/unfold/widgets/textarea.html +1 -7
- unfold/templates/unfold/widgets/textarea_expandable.html +7 -0
- unfold/widgets.py +36 -3
- unfold/contrib/import_export/admin.py +0 -37
- {django_unfold-0.24.0.dist-info → django_unfold-0.26.0.dist-info}/LICENSE.md +0 -0
- {django_unfold-0.24.0.dist-info → django_unfold-0.26.0.dist-info}/WHEEL +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: django-unfold
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.26.0
|
4
4
|
Summary: Modern Django admin theme for seamless interface development
|
5
5
|
Home-page: https://unfoldadmin.com
|
6
6
|
License: MIT
|
@@ -30,7 +30,7 @@ Description-Content-Type: text/markdown
|
|
30
30
|
|
31
31
|
[](https://github.com/unfoldadmin/django-unfold/actions?query=workflow%3Arelease)
|
32
32
|
[](https://pypi.org/project/django-unfold/)
|
33
|
-

|
34
34
|

|
35
35
|
|
36
36
|
Unfold is theme for Django admin incorporating most common practises for building full-fledged admin areas. It is designed to work at the top of default administration provided by Django.
|
@@ -59,7 +59,8 @@ Did you decide to start using Unfold but you don't have time to make the switch
|
|
59
59
|
- **Colors:** possibility to override default color scheme
|
60
60
|
- **Third party packages:** default support for multiple popular applications
|
61
61
|
- **Environment label**: distinguish between environments by displaying a label
|
62
|
-
- **
|
62
|
+
- **Nonrelated inlines**: displays nonrelated model as inline in changeform
|
63
|
+
- **Parallel admin**: support for default admin in parallel with Unfold. [Admin migration guide](https://unfoldadmin.com/blog/migrating-django-admin-unfold/)
|
63
64
|
- **VS Code**: project configuration and development container is included
|
64
65
|
|
65
66
|
## Table of contents <!-- omit from toc -->
|
@@ -78,6 +79,7 @@ Did you decide to start using Unfold but you don't have time to make the switch
|
|
78
79
|
- [Dropdown filters](#dropdown-filters)
|
79
80
|
- [Numeric filters](#numeric-filters)
|
80
81
|
- [Date/time filters](#datetime-filters)
|
82
|
+
- [Nonrelated inlines](#nonrelated-inlines)
|
81
83
|
- [Display decorator](#display-decorator)
|
82
84
|
- [Change form tabs](#change-form-tabs)
|
83
85
|
- [Third party packages](#third-party-packages)
|
@@ -114,6 +116,7 @@ INSTALLED_APPS = [
|
|
114
116
|
"unfold", # before django.contrib.admin
|
115
117
|
"unfold.contrib.filters", # optional, if special filters are needed
|
116
118
|
"unfold.contrib.forms", # optional, if special form elements are needed
|
119
|
+
"unfold.contrib.inlines", # optional, if special inlines are needed
|
117
120
|
"unfold.contrib.import_export", # optional, if django-import-export package is used
|
118
121
|
"unfold.contrib.guardian", # optional, if django-guardian package is used
|
119
122
|
"unfold.contrib.simple_history", # optional, if django-simple-history package is used
|
@@ -633,6 +636,41 @@ class YourModelAdmin(ModelAdmin):
|
|
633
636
|
)
|
634
637
|
```
|
635
638
|
|
639
|
+
## Nonrelated inlines
|
640
|
+
|
641
|
+
To display inlines which are not related (no foreign key pointing at the main model) to the model instance in changeform, you can use nonrelated inlines which are included in `unfold.contrib.inlines` module. Make sure this module is included in `INSTALLED_APPS` in settings.py.
|
642
|
+
|
643
|
+
```python
|
644
|
+
from django.contrib.auth.models import User
|
645
|
+
from unfold.admin import ModelAdmin
|
646
|
+
from unfold.contrib.inlines.admin import NonrelatedTabularInline
|
647
|
+
from .models import OtherModel
|
648
|
+
|
649
|
+
class OtherNonrelatedInline(NonrelatedTabularInline): # NonrelatedStackedInline is available as well
|
650
|
+
model = OtherModel
|
651
|
+
fields = ["field1", "field2"] # Ignore property to display all fields
|
652
|
+
|
653
|
+
def get_form_queryset(self, obj):
|
654
|
+
"""
|
655
|
+
Gets all nonrelated objects needed for inlines. Method must be implemented.
|
656
|
+
"""
|
657
|
+
return self.model.objects.all()
|
658
|
+
|
659
|
+
def save_new_instance(self, parent, instance):
|
660
|
+
"""
|
661
|
+
Extra save method which can for example update inline instances based on current
|
662
|
+
main model object. Method must be implemented.
|
663
|
+
"""
|
664
|
+
pass
|
665
|
+
|
666
|
+
|
667
|
+
@admin.register(User)
|
668
|
+
class UserAdmin(ModelAdmin):
|
669
|
+
inlines = [OtherNonrelatedInline]
|
670
|
+
```
|
671
|
+
|
672
|
+
**NOTE:** credit for this functionality goes to [django-nonrelated-inlines](https://github.com/bhomnick/django-nonrelated-inlines)
|
673
|
+
|
636
674
|
## Display decorator
|
637
675
|
|
638
676
|
Unfold introduces it's own `unfold.decorators.display` decorator. By default it has exactly same behavior as native `django.contrib.admin.decorators.display` but it adds same customizations which helps to extends default logic.
|
@@ -697,12 +735,15 @@ class UserAdmin(ModelAdmin):
|
|
697
735
|
"""
|
698
736
|
return [
|
699
737
|
"First main heading",
|
700
|
-
"Smaller additional description",
|
701
|
-
"AB",
|
738
|
+
"Smaller additional description", # Use None in case you don't need it
|
739
|
+
"AB", # Short text which will appear in front of
|
702
740
|
# Image instead of initials. Initials are ignored if image is available
|
703
741
|
{
|
704
742
|
"path": "some/path/picture.jpg,
|
705
743
|
"squared": True, # Picture is displayed in square format, if empty circle
|
744
|
+
"borderless": True # Picture will be displayed without border
|
745
|
+
"width": 64, # Removes default width. Use together with height
|
746
|
+
"height": 48, # Removes default height. Use together with width
|
706
747
|
}
|
707
748
|
]
|
708
749
|
```
|
@@ -822,15 +863,18 @@ Adding support for django-guardian is quote straightforward in Unfold, just add
|
|
822
863
|
|
823
864
|
from unfold.admin import ModelAdmin
|
824
865
|
from import_export.admin import ImportExportModelAdmin
|
825
|
-
from unfold.contrib.import_export.forms import ExportForm, ImportForm
|
866
|
+
from unfold.contrib.import_export.forms import ExportForm, ImportForm, SelectableFieldsExportForm
|
826
867
|
|
827
868
|
class ExampleAdmin(ModelAdmin, ImportExportModelAdmin):
|
828
869
|
import_form_class = ImportForm
|
829
870
|
export_form_class = ExportForm
|
871
|
+
# export_form_class = SelectableFieldsExportForm
|
830
872
|
```
|
831
873
|
|
832
874
|
When implementing `import_export.admin.ExportActionModelAdmin` class in admin panel, import_export plugin adds its own implementation of action form which is not incorporating Unfold CSS classes. For this reason, `unfold.contrib.import_export.admin` contains class with the same name `ExportActionModelAdmin` which inherits behavior of parent form and adds appropriate CSS classes.
|
833
875
|
|
876
|
+
**Note:** This class has been removed and in new version (4.x) of django-import-export it is not needed.
|
877
|
+
|
834
878
|
```python
|
835
879
|
admin.py
|
836
880
|
|
@@ -1135,6 +1179,7 @@ The container has already a node preinstalled so it is possible to compile a new
|
|
1135
1179
|
|
1136
1180
|
## Credits
|
1137
1181
|
|
1182
|
+
- [django-nonrelated-inlines](https://github.com/bhomnick/django-nonrelated-inlines) - Django admin inlines for unrelated models
|
1138
1183
|
- [TailwindCSS](https://tailwindcss.com/) - CSS framework
|
1139
1184
|
- [HTMX](https://htmx.org/) - AJAX communication with backend
|
1140
1185
|
- [Material Icons](https://fonts.google.com/icons) - Icons from Google Fonts
|
@@ -1,5 +1,5 @@
|
|
1
1
|
unfold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
unfold/admin.py,sha256=
|
2
|
+
unfold/admin.py,sha256=ATDHEq87eC1zgtoObwqTCpRKqJbl0yrS0rf6AAHZTxM,24133
|
3
3
|
unfold/apps.py,sha256=SlBXPYrUd2uXn67qFbRvbXSUk3XFWrF4-5WELgDCvho,381
|
4
4
|
unfold/checks.py,sha256=Smgji9w19hnYjJElJ_FJnnyTEAE-E-OUB6otHu7lasY,1670
|
5
5
|
unfold/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -36,20 +36,26 @@ unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_user.htm
|
|
36
36
|
unfold/contrib/guardian/templates/unfold/guardian/group_form.html,sha256=P8WMC5EejUHV5AxEiIQ2LOGzefLHk5J5UHiNq9wnBgY,4145
|
37
37
|
unfold/contrib/guardian/templates/unfold/guardian/user_form.html,sha256=ci7FRrhTEKbFKKxsJ-07_dWXBYz4mqXPoqu5HfqYLaM,4132
|
38
38
|
unfold/contrib/import_export/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
39
|
-
unfold/contrib/import_export/admin.py,sha256=h6CKRuvloEdxcVScycTSAShXEfzEAsL75uMj2ullhOM,1151
|
40
39
|
unfold/contrib/import_export/apps.py,sha256=SdJu6Qh90VqGWY19FSDhhpUqhTbaIYsJKny3zX5baHI,149
|
41
|
-
unfold/contrib/import_export/forms.py,sha256=
|
40
|
+
unfold/contrib/import_export/forms.py,sha256=cmUUiULJo771rbxf-uCarrbRNwvzCIketbP_7eFnvGc,1496
|
42
41
|
unfold/contrib/import_export/templates/admin/import_export/base.html,sha256=loL2qcV-f8aAzkHss_I4IkwfgemVW2CjOu_aiBxdwX0,357
|
42
|
+
unfold/contrib/import_export/templates/admin/import_export/change_form.html,sha256=_YorgltKO0CRSaLBAp67XnGMUBWEP_XewsUff0hlrE4,446
|
43
43
|
unfold/contrib/import_export/templates/admin/import_export/change_list_export_item.html,sha256=pTDeqPKOlCPKH2dxMIfPnWuc2wVDzB7AzL73WbxSnRY,257
|
44
44
|
unfold/contrib/import_export/templates/admin/import_export/change_list_import_export.html,sha256=JdKd6P2Ot9Ou4yg4CywTauuE1UiTz_mRvDwlx3vj3LI,229
|
45
45
|
unfold/contrib/import_export/templates/admin/import_export/change_list_import_item.html,sha256=XUuRxnsx9YQbKvW-E_JGl_ha7kpTSGSoRefOTTizuX0,233
|
46
|
-
unfold/contrib/import_export/templates/admin/import_export/export.html,sha256=
|
46
|
+
unfold/contrib/import_export/templates/admin/import_export/export.html,sha256=a0gL1YvlFTYQEpJuab-Ue_YL86UO5VkfREqy5CepZUg,3481
|
47
47
|
unfold/contrib/import_export/templates/admin/import_export/import.html,sha256=P54_f3s96PV87Bo-FCZfmsn9DkRXLOB36r7HYF6y7GM,2075
|
48
48
|
unfold/contrib/import_export/templates/admin/import_export/import_confirm.html,sha256=M-acK4XSLHuPFD_NJashGYvPPeJrJsC-3LMvHs3lRis,867
|
49
49
|
unfold/contrib/import_export/templates/admin/import_export/import_errors.html,sha256=0DmJvZs31u-E2Y53yySci86cTnG9aUnOzvfYrOo0lYA,1422
|
50
|
-
unfold/contrib/import_export/templates/admin/import_export/import_form.html,sha256=
|
50
|
+
unfold/contrib/import_export/templates/admin/import_export/import_form.html,sha256=mMuMTAbgMbJ1IyCQPBkzmob4m5lJmZ69_QSo3GvvSiY,990
|
51
51
|
unfold/contrib/import_export/templates/admin/import_export/import_preview.html,sha256=pNuLDW6zc5yOF1jurL2EgR0j05RL9ZVJLZiV4R21GJc,2413
|
52
52
|
unfold/contrib/import_export/templates/admin/import_export/import_validation.html,sha256=1wQOiXN_Ga9VO6GGyl__KEiuJlCh4gTqzZdzIbmKxG0,4880
|
53
|
+
unfold/contrib/import_export/templates/admin/import_export/resource_fields_list.html,sha256=7LzgBiT73c4GHVZx3-ap_cuMz57EnIJ1ESGA5xR31mM,871
|
54
|
+
unfold/contrib/inlines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
55
|
+
unfold/contrib/inlines/admin.py,sha256=p55cNAFOwEFToyFdXUtGl6Vt6j89s9i42V4kHYSZ5Ws,5928
|
56
|
+
unfold/contrib/inlines/apps.py,sha256=Z9JBnzywq-DanZbD56fG0ndBfLXbojzkjVBleqoOBSU,136
|
57
|
+
unfold/contrib/inlines/checks.py,sha256=8sdyBcxw0erqQvp9sHlpGgy0rXfum-cd2eQE0rXFKQ0,559
|
58
|
+
unfold/contrib/inlines/forms.py,sha256=R9OJvrbqNLlKvTxw97JjElCY4CQ3IyRIkjIJUN0gJ9k,1323
|
53
59
|
unfold/contrib/simple_history/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
60
|
unfold/contrib/simple_history/apps.py,sha256=eF_KVYb60CAnGgWk2Z1YKYGfgA3TJBMr229qI7e2pgU,153
|
55
61
|
unfold/contrib/simple_history/templates/simple_history/_object_history_list.html,sha256=aXOQ1zwsRBlFmzODsZApvMtb8t1IPXim6i4plXUR5XE,5112
|
@@ -59,10 +65,11 @@ unfold/contrib/simple_history/templates/simple_history/submit_line.html,sha256=n
|
|
59
65
|
unfold/dataclasses.py,sha256=JJdGYzQ8MpeOe2FQPJqrMn_UJcxUz1VJgHCuCtkZCA8,199
|
60
66
|
unfold/decorators.py,sha256=BVDlxhZxB4ND3f5-5oiENRTv_W_Q_Eu-gZlsrYKOxiU,3272
|
61
67
|
unfold/exceptions.py,sha256=gcCj1ox61E137bk_0Cqy4YC3SttdPgB-fiJUqpmyHSE,43
|
62
|
-
unfold/forms.py,sha256=
|
68
|
+
unfold/forms.py,sha256=GXEm3CFwglyuEbGdVyEMJTB45Gs-_RvGGlXJEkPy2kw,3688
|
63
69
|
unfold/settings.py,sha256=--TdTSWdOA8TQGW4-vjJkjy_zEyd_kZwBr3BIuQ8hzI,1208
|
64
70
|
unfold/sites.py,sha256=Gy_i43j2nizW2g8-mas5icvtk-beKism_CznATW6Ia8,12586
|
65
|
-
unfold/static/unfold/css/
|
71
|
+
unfold/static/unfold/css/simplebar.css,sha256=5LLaEM11pKi6JFCOLt4XKuZxTpT9rpdq_tNlaQytFlU,4647
|
72
|
+
unfold/static/unfold/css/styles.css,sha256=hlPYMtAEeIPl7yIFpqMR4DqJwz9K2RLhpbI4aSNq6mU,91675
|
66
73
|
unfold/static/unfold/fonts/inter/Inter-Bold.woff2,sha256=O88EyjAeRPE_QEyKBKpK5wf2epUOEu8wwjj5bnhCZqE,46552
|
67
74
|
unfold/static/unfold/fonts/inter/Inter-Medium.woff2,sha256=O88EyjAeRPE_QEyKBKpK5wf2epUOEu8wwjj5bnhCZqE,46552
|
68
75
|
unfold/static/unfold/fonts/inter/Inter-Regular.woff2,sha256=O88EyjAeRPE_QEyKBKpK5wf2epUOEu8wwjj5bnhCZqE,46552
|
@@ -75,26 +82,27 @@ unfold/static/unfold/js/alpine.persist.js,sha256=84PZYnPi25AFm7wIWRe1gzA74c5Rv2V
|
|
75
82
|
unfold/static/unfold/js/app.js,sha256=CIitJoFqpeZYPw8icGVXYX9tVRUgqFxcPZ2WjWS8Ylk,5288
|
76
83
|
unfold/static/unfold/js/chart.js,sha256=22W6cFERR-CElMOKRgMMicueMVP0Vf7FBEBYH8Z8tCk,200633
|
77
84
|
unfold/static/unfold/js/htmx.js,sha256=XOLqvnZiyEx46EW9vaJTBUaaWg8CGVVfXJkVsUmJbpI,42820
|
78
|
-
unfold/
|
85
|
+
unfold/static/unfold/js/simplebar.js,sha256=t-uG1FAD6ZoiMeN--wac0XRS7SxoDVG6zvRnGuEp7X8,27176
|
86
|
+
unfold/styles.css,sha256=JA2ybI-pzRM4ZOKshI187oJ5Z3gMNWHQAuEfwq5Xb_E,17854
|
79
87
|
unfold/templates/admin/actions.html,sha256=1tVlUpLoM72K2Ew4vQGcRwPjHuAtO5Jm4QdDsDLOq0I,2625
|
80
88
|
unfold/templates/admin/app_index.html,sha256=lVjMIFsspHQ09LGHKfdfg7TlqlL39AX5LbwoeoZjFhk,1335
|
81
|
-
unfold/templates/admin/app_list.html,sha256=
|
89
|
+
unfold/templates/admin/app_list.html,sha256=krDzw2EXqqvIi8bJtPhJsNran9H7hwdhM6ZW_IRlDwQ,3038
|
82
90
|
unfold/templates/admin/auth/user/add_form.html,sha256=iLig-vd2YExXsj0xGBwYhZ4kGUihwYtLtNVhzObgSzg,478
|
83
91
|
unfold/templates/admin/auth/user/change_password.html,sha256=-Wa9ml3yss-kDz0YQxCiwoxs91KQD8eetCt5l6xekWM,2892
|
84
92
|
unfold/templates/admin/base.html,sha256=MGqtCcydXZPnp6dasaWktyd9D6rdUYX01rFGAv7Zkm4,2226
|
85
93
|
unfold/templates/admin/base_site.html,sha256=3ckWrcAdd7Pw1hk6Zwyknab_Qb-rteV9-mXhMnfo6VI,361
|
86
|
-
unfold/templates/admin/change_form.html,sha256
|
94
|
+
unfold/templates/admin/change_form.html,sha256=OvegZJTH4eGHXf5RJOHfy9tXKCtyml_Yl8pENb9kNq8,5431
|
87
95
|
unfold/templates/admin/change_form_object_tools.html,sha256=eyeH-i2HgEM0Yi-OJA2D1VnKJyC19A_my1IDGxxoP8Y,593
|
88
96
|
unfold/templates/admin/change_list.html,sha256=18GDZswc1c0xtw2BcKti9SX95Ar9e1BX_HSY0K79g_8,5102
|
89
97
|
unfold/templates/admin/change_list_object_tools.html,sha256=cmMiT2nT20Ph5yfpj9aHPr76Z-JP4aSXp0o-Rnad28s,147
|
90
|
-
unfold/templates/admin/change_list_results.html,sha256=
|
98
|
+
unfold/templates/admin/change_list_results.html,sha256=Ie2NGfIiU0HHy1a5wJ-YJV1doZkibVRCmR3DRZdoV2I,5395
|
91
99
|
unfold/templates/admin/date_hierarchy.html,sha256=BfUPbsLpHZVa40BHBahz1H9RSVuz36Jc3yrlobOiIpw,1306
|
92
100
|
unfold/templates/admin/delete_confirmation.html,sha256=hpa2E14oZEXBBs6W1qdNQuF650TIO2Rhr52Q6UfwVeQ,5166
|
93
101
|
unfold/templates/admin/delete_selected_confirmation.html,sha256=Foka2yvwAMEZre-Kh1KNadRzrCotdKM2U4e6AJQYZu8,4941
|
94
|
-
unfold/templates/admin/edit_inline/stacked.html,sha256=
|
95
|
-
unfold/templates/admin/edit_inline/tabular.html,sha256=
|
102
|
+
unfold/templates/admin/edit_inline/stacked.html,sha256=HG-Dj42gcKNofHRVjg0ltIER2oJGYUd9GN_B7lDv7rQ,4580
|
103
|
+
unfold/templates/admin/edit_inline/tabular.html,sha256=mVlQ5aJr6-GdHM2zaWVUKaa6gok3Vv3MAMQj0sIX-lQ,12976
|
96
104
|
unfold/templates/admin/filter.html,sha256=dkrFkei-EAlldIU8DrgvSChzWQuUOu6-LS_qlZxdfFw,1708
|
97
|
-
unfold/templates/admin/includes/fieldset.html,sha256=
|
105
|
+
unfold/templates/admin/includes/fieldset.html,sha256=qVxXy7KRI8GC4bIBPO9hjQlMtDg83vhEZbmVXqdfrgg,2929
|
98
106
|
unfold/templates/admin/includes/object_delete_summary.html,sha256=Nv69SCzyJHFX14iJFfodxKM0IIpQegKZH0fvKB15QJI,468
|
99
107
|
unfold/templates/admin/index.html,sha256=pkGdKWdD3zzOvkRdELvdb15sleSpfl4eHPA14PAh7z0,684
|
100
108
|
unfold/templates/admin/login.html,sha256=WdOfFLofwBWj9VKCq1U22uLY19J2YQY6vRaE4OOSKfQ,3681
|
@@ -121,17 +129,17 @@ unfold/templates/unfold/components/title.html,sha256=PSiNK-s8jUJfu6f9zCcGOOyLiKx
|
|
121
129
|
unfold/templates/unfold/helpers/account_links.html,sha256=Kc1FobAVN3B34x9vcMoEXyuQ45d5SjfjaJSo3UErL3Q,1934
|
122
130
|
unfold/templates/unfold/helpers/actions_row.html,sha256=1xd39zx38NOoKuDuxAG7PHeu5x2OTIraQGFkm15Erqg,1681
|
123
131
|
unfold/templates/unfold/helpers/add_link.html,sha256=mIgpKrwqBO1oJ4cwPQWSX1oUHBwHJmy5-2TxUHf-1bo,808
|
124
|
-
unfold/templates/unfold/helpers/app_list.html,sha256=
|
132
|
+
unfold/templates/unfold/helpers/app_list.html,sha256=lFnW8p9DcZbI9t3_ee9JX9ERHA0NRL2V88zpzuG4jq8,4720
|
125
133
|
unfold/templates/unfold/helpers/app_list_default.html,sha256=vZkw1F7oHOKReNkdHRYjhuNdA1nNdvSD4wbDmf0bnsM,4102
|
126
134
|
unfold/templates/unfold/helpers/boolean.html,sha256=p_WOlytoXvDwta76WgcV4JSWKpBgKf4amhqmHF798F8,564
|
127
135
|
unfold/templates/unfold/helpers/breadcrumb_item.html,sha256=k_1j57UV0WtzFFlMKaewj4NLbR_DhXI6RzCHThblZLw,234
|
128
|
-
unfold/templates/unfold/helpers/display_header.html,sha256=
|
136
|
+
unfold/templates/unfold/helpers/display_header.html,sha256=RR3HexzdO3YazPSJYfF9UfujCDiJ_EDrmnfxDFNLd7U,1160
|
129
137
|
unfold/templates/unfold/helpers/display_label.html,sha256=LS9DWzYjHkYLV27sZDwyXlg2sLJ0AlId9FbjnXpsbfg,317
|
130
|
-
unfold/templates/unfold/helpers/field.html,sha256=
|
138
|
+
unfold/templates/unfold/helpers/field.html,sha256=Ds-zUHkdyxamfUCVNhxvtM0XoJg9OCA0QcsLbLWv4oo,882
|
131
139
|
unfold/templates/unfold/helpers/field_readonly.html,sha256=v7-2oSSDgOsuYpP70y8DqdBqbRybubAfSDzstveoBuw,382
|
132
|
-
unfold/templates/unfold/helpers/fieldsets_tabs.html,sha256
|
140
|
+
unfold/templates/unfold/helpers/fieldsets_tabs.html,sha256=V3bgW75eozaBDty-xfciGafhCWq_Ba5HfQkk92yRc9A,1445
|
133
141
|
unfold/templates/unfold/helpers/form_errors.html,sha256=EwerIJptSCWXvtAJ1IZKfEn98qlShBIGavsTThbklAs,266
|
134
|
-
unfold/templates/unfold/helpers/form_label.html,sha256=
|
142
|
+
unfold/templates/unfold/helpers/form_label.html,sha256=SR4U6iK9w4oels6iGY_Da-yN4BbXQVN9zCDlBGGXcw8,310
|
135
143
|
unfold/templates/unfold/helpers/header.html,sha256=jklASqVEJRa22jxdXq_X2UZb2uYn_ywaZbI2N4nBv20,998
|
136
144
|
unfold/templates/unfold/helpers/help_text.html,sha256=iBXw0LWfoYT5PoPLJek9ixv4SuK7hfVkjPgmv2ODW-s,146
|
137
145
|
unfold/templates/unfold/helpers/history.html,sha256=0_Imm7Fc1PqjjXEmHh8QEQg_qIqBZWx2BeK5o3axfvY,2017
|
@@ -154,10 +162,11 @@ unfold/templates/unfold/helpers/theme_switch.html,sha256=skkl6fYUnYLM7fAPivHxWjn
|
|
154
162
|
unfold/templates/unfold/helpers/userlinks.html,sha256=qWjtBt9Q_tU8a874ii0Qqg8t_d-SSYBTB_3QZfNlx9g,634
|
155
163
|
unfold/templates/unfold/helpers/welcomemsg.html,sha256=noRysgSENef4_53pXaTiBCy2or6lQm1ZtmCQVODAB1c,1120
|
156
164
|
unfold/templates/unfold/layouts/base_simple.html,sha256=rki7n7QagHFAaCEn488pTOj9dpNL9AwwzKps8Ipiubk,993
|
157
|
-
unfold/templates/unfold/layouts/skeleton.html,sha256=
|
165
|
+
unfold/templates/unfold/layouts/skeleton.html,sha256=iXrUiggVp36vmBIia5p32c-9Ruy0PxkFFQogDpvENbk,3419
|
158
166
|
unfold/templates/unfold/widgets/clearable_file_input.html,sha256=vXsyP0-YD-z3z6VL4vXW9pJH9_-ZU9u-3AnmZkni-R4,1994
|
159
167
|
unfold/templates/unfold/widgets/clearable_file_input_small.html,sha256=rqUnHF4jwL8_RySUuq2aXgj-0P_usgo1HeVT_IcfyFY,2531
|
160
168
|
unfold/templates/unfold/widgets/date.html,sha256=WXo2LG1v_gBZBSg-zocj7oujMKI0MWLYCIFfB04HMLQ,122
|
169
|
+
unfold/templates/unfold/widgets/foreign_key_raw_id.html,sha256=26UGK04ojS-ZsvhWpPIbr6VE9b91Q2sEhB7FBkMY1NI,917
|
161
170
|
unfold/templates/unfold/widgets/radio.html,sha256=3WcmclQNg7R_pRjEHL1dHkGjAzWlWNYnhHkAirC4nuA,646
|
162
171
|
unfold/templates/unfold/widgets/radio_option.html,sha256=IZgPx-aWKJuxrSalJ3K50RFd1vwSpb9Qk0yZwfV78_A,368
|
163
172
|
unfold/templates/unfold/widgets/range.html,sha256=28FBtSUgUcG82vpk_I27Lbs5oWZOV_oMzVhx4wj3-Ik,262
|
@@ -165,7 +174,8 @@ unfold/templates/unfold/widgets/related_widget_wrapper.html,sha256=0I6wSu8z_sJPq
|
|
165
174
|
unfold/templates/unfold/widgets/split_datetime.html,sha256=eXLFZyCv84LCTFWAUhNO3xAIzWvGBvI1ZpYbB38_HOI,862
|
166
175
|
unfold/templates/unfold/widgets/split_datetime_vertical.html,sha256=xinCH4kkQ-yKUqcSI7-m-_UEzOEKWqvLTjUa3i-e8EM,881
|
167
176
|
unfold/templates/unfold/widgets/split_money.html,sha256=AFLUBmzGbY-RXgsfz7gaDxVRhplaIPhXjg_hWYo9xcY,352
|
168
|
-
unfold/templates/unfold/widgets/textarea.html,sha256
|
177
|
+
unfold/templates/unfold/widgets/textarea.html,sha256=-ZLDGrtASero7L-J3VvTNq_KjPAZh_kLVw0Ow3awqXM,144
|
178
|
+
unfold/templates/unfold/widgets/textarea_expandable.html,sha256=4xIGWb20DuwiwumndByrAyh7xF-ReXKLulSpDImX_cs,459
|
169
179
|
unfold/templates/unfold/widgets/time.html,sha256=WXo2LG1v_gBZBSg-zocj7oujMKI0MWLYCIFfB04HMLQ,122
|
170
180
|
unfold/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
171
181
|
unfold/templatetags/unfold.py,sha256=HFe0GrTD4va0lLzsZhxqjEOONmehqOWdf5vulkxgfGU,6302
|
@@ -173,8 +183,8 @@ unfold/templatetags/unfold_list.py,sha256=5xAjQX0_JnVwDaj-wGkGqbjOAtp-a18koWIKj5
|
|
173
183
|
unfold/typing.py,sha256=1P8PWM2oeaceUJtA5j071RbKEBpHYaux441u7Hd6wv4,643
|
174
184
|
unfold/utils.py,sha256=5OIgDcwvIJQbwbnnqHx61cHh-2T1h184mTAuNq5WXLI,4088
|
175
185
|
unfold/views.py,sha256=Ml3XlEoHLcbEWof59Dw8ihKBMcmp-gBAibThtBFj55A,708
|
176
|
-
unfold/widgets.py,sha256=
|
177
|
-
django_unfold-0.
|
178
|
-
django_unfold-0.
|
179
|
-
django_unfold-0.
|
180
|
-
django_unfold-0.
|
186
|
+
unfold/widgets.py,sha256=iiI73XznYH34LgXBHu1oVtYb76lLO3HiOD9blmm89rY,15236
|
187
|
+
django_unfold-0.26.0.dist-info/LICENSE.md,sha256=Ltk_quRyyvV3J5v3brtOqmibeZSw2Hrb8bY1W3ya0Ik,1077
|
188
|
+
django_unfold-0.26.0.dist-info/METADATA,sha256=UUv_H7BwNNquFABkpQ1PObEBBKknsGFxkyDnkk3l5oU,48746
|
189
|
+
django_unfold-0.26.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
190
|
+
django_unfold-0.26.0.dist-info/RECORD,,
|
unfold/admin.py
CHANGED
@@ -55,6 +55,7 @@ from .widgets import (
|
|
55
55
|
UnfoldAdminBigIntegerFieldWidget,
|
56
56
|
UnfoldAdminDecimalFieldWidget,
|
57
57
|
UnfoldAdminEmailInputWidget,
|
58
|
+
UnfoldAdminFileFieldWidget,
|
58
59
|
UnfoldAdminImageFieldWidget,
|
59
60
|
UnfoldAdminImageSmallFieldWidget,
|
60
61
|
UnfoldAdminIntegerFieldWidget,
|
@@ -71,6 +72,7 @@ from .widgets import (
|
|
71
72
|
UnfoldAdminUUIDInputWidget,
|
72
73
|
UnfoldBooleanSwitchWidget,
|
73
74
|
UnfoldBooleanWidget,
|
75
|
+
UnfoldForeignKeyRawIdWidget,
|
74
76
|
)
|
75
77
|
|
76
78
|
try:
|
@@ -109,6 +111,7 @@ FORMFIELD_OVERRIDES = {
|
|
109
111
|
models.BigIntegerField: {"widget": UnfoldAdminBigIntegerFieldWidget},
|
110
112
|
models.DecimalField: {"widget": UnfoldAdminDecimalFieldWidget},
|
111
113
|
models.FloatField: {"widget": UnfoldAdminDecimalFieldWidget},
|
114
|
+
models.FileField: {"widget": UnfoldAdminFileFieldWidget},
|
112
115
|
models.ImageField: {"widget": UnfoldAdminImageFieldWidget},
|
113
116
|
models.JSONField: {"widget": UnfoldAdminTextareaWidget},
|
114
117
|
models.DurationField: {"widget": UnfoldAdminTextInputWidget},
|
@@ -142,7 +145,6 @@ FORMFIELD_OVERRIDES_INLINE.update(
|
|
142
145
|
class UnfoldAdminField(helpers.AdminField):
|
143
146
|
def label_tag(self) -> SafeText:
|
144
147
|
classes = []
|
145
|
-
|
146
148
|
if not self.field.field.widget.__class__.__name__.startswith(
|
147
149
|
"Unfold"
|
148
150
|
) and not self.field.field.widget.template_name.startswith("unfold"):
|
@@ -181,7 +183,9 @@ helpers.AdminField = UnfoldAdminField
|
|
181
183
|
|
182
184
|
class UnfoldAdminReadonlyField(helpers.AdminReadonlyField):
|
183
185
|
def label_tag(self) -> SafeText:
|
184
|
-
if not isinstance(self.model_admin, ModelAdmin)
|
186
|
+
if not isinstance(self.model_admin, ModelAdmin) and not isinstance(
|
187
|
+
self.model_admin, ModelAdminMixin
|
188
|
+
):
|
185
189
|
return super().label_tag()
|
186
190
|
|
187
191
|
attrs = {
|
@@ -305,10 +309,14 @@ class ModelAdminMixin:
|
|
305
309
|
def formfield_for_foreignkey(
|
306
310
|
self, db_field: ForeignKey, request: HttpRequest, **kwargs
|
307
311
|
) -> Optional[ModelChoiceField]:
|
312
|
+
db = kwargs.get("using")
|
313
|
+
|
308
314
|
# Overrides widgets for all related fields
|
309
315
|
if "widget" not in kwargs:
|
310
316
|
if db_field.name in self.raw_id_fields:
|
311
|
-
kwargs["widget"] =
|
317
|
+
kwargs["widget"] = UnfoldForeignKeyRawIdWidget(
|
318
|
+
db_field.remote_field, self.admin_site, using=db
|
319
|
+
)
|
312
320
|
elif (
|
313
321
|
db_field.name not in self.get_autocomplete_fields(request)
|
314
322
|
and db_field.name not in self.radio_fields
|
@@ -1,15 +1,38 @@
|
|
1
|
-
from
|
2
|
-
from
|
1
|
+
from django.forms.fields import BooleanField
|
2
|
+
from import_export.forms import ExportForm as BaseExportForm
|
3
|
+
from import_export.forms import ImportForm as BaseImportForm
|
4
|
+
from import_export.forms import (
|
5
|
+
SelectableFieldsExportForm as BaseSelectableFieldsExportForm,
|
6
|
+
)
|
7
|
+
from unfold.widgets import (
|
8
|
+
SELECT_CLASSES,
|
9
|
+
UnfoldAdminFileFieldWidget,
|
10
|
+
UnfoldBooleanWidget,
|
11
|
+
)
|
3
12
|
|
4
13
|
|
5
|
-
class ImportForm(
|
14
|
+
class ImportForm(BaseImportForm):
|
6
15
|
def __init__(self, *args, **kwargs):
|
7
16
|
super().__init__(*args, **kwargs)
|
8
|
-
|
17
|
+
|
18
|
+
self.fields["resource"].widget.attrs["class"] = " ".join(SELECT_CLASSES)
|
19
|
+
self.fields["import_file"].widget = UnfoldAdminFileFieldWidget()
|
9
20
|
self.fields["format"].widget.attrs["class"] = " ".join(SELECT_CLASSES)
|
10
21
|
|
11
22
|
|
12
|
-
class ExportForm(
|
23
|
+
class ExportForm(BaseExportForm):
|
13
24
|
def __init__(self, *args, **kwargs):
|
14
25
|
super().__init__(*args, **kwargs)
|
26
|
+
self.fields["resource"].widget.attrs["class"] = " ".join(SELECT_CLASSES)
|
15
27
|
self.fields["format"].widget.attrs["class"] = " ".join(SELECT_CLASSES)
|
28
|
+
|
29
|
+
|
30
|
+
class SelectableFieldsExportForm(BaseSelectableFieldsExportForm):
|
31
|
+
def __init__(self, formats, resources, **kwargs):
|
32
|
+
super().__init__(formats, resources, **kwargs)
|
33
|
+
self.fields["resource"].widget.attrs["class"] = " ".join(SELECT_CLASSES)
|
34
|
+
self.fields["format"].widget.attrs["class"] = " ".join(SELECT_CLASSES)
|
35
|
+
|
36
|
+
for _key, field in self.fields.items():
|
37
|
+
if isinstance(field, BooleanField):
|
38
|
+
field.widget = UnfoldBooleanWidget()
|
@@ -0,0 +1,10 @@
|
|
1
|
+
{% extends 'admin/change_form.html' %}
|
2
|
+
{% load i18n %}
|
3
|
+
|
4
|
+
{% block actions %}
|
5
|
+
{{ block.super }}
|
6
|
+
|
7
|
+
{% if show_change_form_export %}
|
8
|
+
<input type="submit" value="{% translate 'Export' %}" name="_export-item" class="bg-white text-gray-500 border cursor-pointer flex font-medium items-center px-3 py-2 mr-3 rounded-md shadow-sm text-sm dark:bg-gray-900 dark:border dark:border-gray-700 dark:text-gray-400">
|
9
|
+
{% endif %}
|
10
|
+
{% endblock %}
|
@@ -33,11 +33,46 @@
|
|
33
33
|
{% endblock %}
|
34
34
|
|
35
35
|
{% block content %}
|
36
|
-
<form action="" method="POST">
|
36
|
+
<form action="{{ export_url }}" method="POST">
|
37
37
|
{% csrf_token %}
|
38
38
|
|
39
|
-
|
40
|
-
|
39
|
+
{% if form.initial.export_items %}
|
40
|
+
<p class="bg-blue-50 mb-4 text-blue-500 px-3 py-3 rounded-md text-sm dark:bg-blue-500/20 dark:border-blue-500/10">
|
41
|
+
{% blocktranslate count len=form.initial.export_items|length %}
|
42
|
+
Export {{ len }} selected item.
|
43
|
+
{% plural %}
|
44
|
+
Export {{ len }} selected items.
|
45
|
+
{% endblocktranslate %}
|
46
|
+
</p>
|
47
|
+
{% endif %}
|
48
|
+
|
49
|
+
{% if not form.is_selectable_fields_form %}
|
50
|
+
{% include "admin/import_export/resource_fields_list.html" with import_or_export="export" %}
|
51
|
+
{% endif %}
|
52
|
+
|
53
|
+
{{ form.non_field_errors }}
|
54
|
+
|
55
|
+
<fieldset class="border border-gray-200 mb-4 rounded-md pt-3 px-3 shadow-sm dark:border-gray-800">
|
56
|
+
{% for field in form.visible_fields %}
|
57
|
+
<div {% if field.field.is_selectable_field %}class="selectable-field-export-row" resource-index="{{ field.field.resource_index }}"{% else %}class="form-row aligned"{% endif %}>
|
58
|
+
{% if field.field.initial_field %}
|
59
|
+
<p class="block font-medium mb-2 text-gray-900 text-sm dark:text-gray-200">
|
60
|
+
{% trans "This exporter will export the following fields" %}
|
61
|
+
</p>
|
62
|
+
{% endif %}
|
63
|
+
|
64
|
+
{% if field.field.widget.attrs.readonly %}
|
65
|
+
{% include "unfold/helpers/field_readonly.html" with title=field.label value=field.field.value %}
|
66
|
+
{{ field.as_hidden }}
|
67
|
+
{% else %}
|
68
|
+
{% include "unfold/helpers/field.html" with field=field %}
|
69
|
+
{% endif %}
|
70
|
+
</div>
|
71
|
+
{% endfor %}
|
72
|
+
|
73
|
+
{% for field in form.hidden_fields %}
|
74
|
+
{{ field }}
|
75
|
+
{% endfor %}
|
41
76
|
</fieldset>
|
42
77
|
|
43
78
|
<button type="submit" class="bg-primary-600 border border-transparent font-medium px-3 py-2 rounded-md text-sm text-white">
|
@@ -4,30 +4,19 @@
|
|
4
4
|
<form action="" method="post" enctype="multipart/form-data">
|
5
5
|
{% csrf_token %}
|
6
6
|
|
7
|
-
|
8
|
-
{% trans "This importer will import the following fields: " %}
|
9
|
-
|
10
|
-
{% if fields_list|length <= 1 %}
|
11
|
-
<span class="font-medium">
|
12
|
-
{{ fields_list.0.1|join:", " }}
|
13
|
-
</code>
|
14
|
-
{% else %}
|
15
|
-
<dl>
|
16
|
-
{% for resource, fields in fields_list %}
|
17
|
-
<dt>{{ resource }}</dt>
|
18
|
-
<dd><code>{{ fields|join:", " }}</code></dd>
|
19
|
-
{% endfor %}
|
20
|
-
</dl>
|
21
|
-
{% endif %}
|
22
|
-
</p>
|
7
|
+
{% include "admin/import_export/resource_fields_list.html" with import_or_export="import" %}
|
23
8
|
|
24
9
|
<fieldset class="border border-gray-200 mb-8 rounded-md pt-3 px-3 shadow-sm dark:border-gray-800">
|
25
|
-
|
26
|
-
|
27
|
-
|
10
|
+
{% for field in form %}
|
11
|
+
{% if field.field.widget.attrs.readonly %}
|
12
|
+
{% include "unfold/helpers/field_readonly.html" with title=field.label value=field.field.value %}
|
13
|
+
{{ field.as_hidden }}
|
14
|
+
{% else %}
|
15
|
+
{% include "unfold/helpers/field.html" with field=field %}
|
16
|
+
{% endif %}
|
17
|
+
{% endfor %}
|
28
18
|
</fieldset>
|
29
19
|
|
30
|
-
|
31
20
|
<button type="submit" class="bg-primary-600 border border-transparent font-medium px-3 py-2 rounded-md text-sm text-white">
|
32
21
|
{% translate 'Submit' %}
|
33
22
|
</button>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{% load i18n %}
|
2
|
+
|
3
|
+
{% block fields_help %}
|
4
|
+
<div class="bg-blue-50 mb-4 text-blue-500 px-3 py-3 rounded-md text-sm dark:bg-blue-500/20 dark:border-blue-500/10">
|
5
|
+
{% if import_or_export == "export" %}
|
6
|
+
{% trans "This exporter will export the following fields: " %}
|
7
|
+
{% elif import_or_export == "import" %}
|
8
|
+
{% trans "This importer will import the following fields: " %}
|
9
|
+
{% endif %}
|
10
|
+
|
11
|
+
{% if fields_list|length <= 1 %}
|
12
|
+
<code class="font-medium">
|
13
|
+
{{ fields_list.0.1|join:", " }}
|
14
|
+
</code>
|
15
|
+
{% else %}
|
16
|
+
<dl>
|
17
|
+
{% for resource, fields in fields_list %}
|
18
|
+
<dt>{{ resource }}</dt>
|
19
|
+
<dd><code>{{ fields|join:", " }}</code></dd>
|
20
|
+
{% endfor %}
|
21
|
+
</dl>
|
22
|
+
{% endif %}
|
23
|
+
</div>
|
24
|
+
{% endblock %}
|
File without changes
|