django-unfold 0.12.0__tar.gz → 0.13.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {django_unfold-0.12.0 → django_unfold-0.13.0}/PKG-INFO +209 -102
- {django_unfold-0.12.0 → django_unfold-0.13.0}/README.md +207 -101
- {django_unfold-0.12.0 → django_unfold-0.13.0}/pyproject.toml +3 -2
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/admin.py +26 -6
- django_unfold-0.13.0/src/unfold/contrib/guardian/apps.py +6 -0
- django_unfold-0.13.0/src/unfold/contrib/guardian/templates/admin/guardian/model/change_form.html +13 -0
- django_unfold-0.13.0/src/unfold/contrib/guardian/templates/admin/guardian/model/field.html +11 -0
- django_unfold-0.13.0/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage.html +35 -0
- django_unfold-0.13.0/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_group.html +55 -0
- django_unfold-0.13.0/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_user.html +56 -0
- django_unfold-0.13.0/src/unfold/contrib/guardian/templates/unfold/guardian/group_form.html +72 -0
- django_unfold-0.13.0/src/unfold/contrib/guardian/templates/unfold/guardian/user_form.html +72 -0
- django_unfold-0.13.0/src/unfold/contrib/simple_history/__init__.py +0 -0
- django_unfold-0.13.0/src/unfold/contrib/simple_history/apps.py +6 -0
- django_unfold-0.13.0/src/unfold/contrib/simple_history/templates/simple_history/_object_history_list.html +80 -0
- django_unfold-0.13.0/src/unfold/contrib/simple_history/templates/simple_history/object_history.html +21 -0
- django_unfold-0.13.0/src/unfold/contrib/simple_history/templates/simple_history/object_history_form.html +55 -0
- django_unfold-0.13.0/src/unfold/contrib/simple_history/templates/simple_history/submit_line.html +25 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/settings.py +1 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/sites.py +4 -0
- django_unfold-0.13.0/src/unfold/static/unfold/css/styles.css +1 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/styles.css +134 -66
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/edit_inline/tabular.html +1 -1
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/includes/fieldset.html +3 -7
- django_unfold-0.13.0/src/unfold/templates/admin/widgets/radio.html +20 -0
- django_unfold-0.13.0/src/unfold/templates/admin/widgets/radio_option.html +12 -0
- django_unfold-0.13.0/src/unfold/templates/unfold/helpers/field_readonly.html +9 -0
- django_unfold-0.13.0/src/unfold/templates/unfold/helpers/submit.html +3 -0
- django_unfold-0.13.0/src/unfold/templatetags/__init__.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templatetags/unfold.py +14 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/widgets.py +19 -0
- django_unfold-0.12.0/src/unfold/static/unfold/css/styles.css +0 -1
- /django_unfold-0.12.0/LICENSE → /django_unfold-0.13.0/LICENSE.md +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/__init__.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/apps.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/checks.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/__init__.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/__init__.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/admin.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/apps.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/forms.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/static/unfold/filters/css/nouislider.min.css +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/static/unfold/filters/js/DateTimeShortcuts.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/static/unfold/filters/js/admin-numeric-filter.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/static/unfold/filters/js/nouislider.min.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/static/unfold/filters/js/wNumb.min.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_date_range.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_datetime_range.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_range.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_single.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/forms/__init__.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/forms/apps.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/forms/static/unfold/forms/css/trix.css +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix.config.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/forms/templates/unfold/forms/helpers/toolbar.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/forms/templates/unfold/forms/wysiwyg.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/forms/widgets.py +0 -0
- {django_unfold-0.12.0/src/unfold/contrib/import_export → django_unfold-0.13.0/src/unfold/contrib/guardian}/__init__.py +0 -0
- {django_unfold-0.12.0/src/unfold/templatetags → django_unfold-0.13.0/src/unfold/contrib/import_export}/__init__.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/apps.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/forms.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/base.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_export_item.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import_export.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import_item.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/export.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/import.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_confirm.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_errors.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_form.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_preview.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_validation.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/dataclasses.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/decorators.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/exceptions.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/forms.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/static/unfold/css/simplebar.css +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/static/unfold/js/alpine.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/static/unfold/js/alpine.persist.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/static/unfold/js/app.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/static/unfold/js/htmx.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/static/unfold/js/simplebar.js +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/actions.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/app_index.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/app_list.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/auth/user/add_form.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/auth/user/change_password.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/base.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/base_site.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/change_form.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/change_form_object_tools.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/change_list.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/change_list_object_tools.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/change_list_results.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/date_hierarchy.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/delete_confirmation.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/delete_selected_confirmation.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/edit_inline/stacked.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/filter.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/includes/object_delete_summary.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/index.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/login.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/nav_sidebar.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/object_history.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/pagination.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/search_form.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/submit_line.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/widgets/clearable_file_input.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/widgets/related_widget_wrapper.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/admin/widgets/split_datetime.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/auth/widgets/read_only_password_hash.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/registration/logged_out.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/registration/password_change_done.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/registration/password_change_form.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/change_list_filter.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/account_links.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/actions_row.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/add_link.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/app_list.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/app_list_default.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/boolean.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/breadcrumb_item.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/display_header.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/display_label.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/field.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/form_errors.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/help_text.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/history.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/label.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/messages/error.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/messages/errornote.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/messages/info.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/messages.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/navigation.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/pagination_current_item.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/pagination_ellipsis.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/search.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/search_results.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/site_icon.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/tab_list.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/theme_switch.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/userlinks.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/helpers/welcomemsg.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/layouts/base_simple.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/layouts/skeleton.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/widgets/clearable_file_input_small.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/widgets/date.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/widgets/range.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/widgets/split_datetime_vertical.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/widgets/split_money.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/widgets/textarea.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templates/unfold/widgets/time.html +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/templatetags/unfold_list.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/typing.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/utils.py +0 -0
- {django_unfold-0.12.0 → django_unfold-0.13.0}/src/unfold/views.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: django-unfold
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.13.0
|
4
4
|
Summary: Clean & minimal Django admin theme based on Tailwind CSS
|
5
5
|
Home-page: https://unfoldadmin.com
|
6
6
|
License: MIT
|
@@ -17,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.9
|
18
18
|
Classifier: Programming Language :: Python :: 3.10
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
20
21
|
Requires-Dist: django (>=3.2)
|
21
22
|
Requires-Dist: importlib-metadata (==6.7.0)
|
22
23
|
Project-URL: Repository, https://github.com/unfoldadmin/django-unfold
|
@@ -24,7 +25,7 @@ Description-Content-Type: text/markdown
|
|
24
25
|
|
25
26
|

|
26
27
|
|
27
|
-
## Unfold Django Admin Theme
|
28
|
+
## Unfold Django Admin Theme <!-- omit from toc -->
|
28
29
|
|
29
30
|
[](https://github.com/unfoldadmin/django-unfold/actions?query=workflow%3Arelease)
|
30
31
|
[](https://pypi.org/project/django-unfold/)
|
@@ -33,11 +34,11 @@ Description-Content-Type: text/markdown
|
|
33
34
|
|
34
35
|
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.
|
35
36
|
|
36
|
-
- demo site is available at [unfoldadmin.com](https://unfoldadmin.com)
|
37
|
-
- repository with demo implementation at [github.com/unfoldadmin/formula](https://github.com/unfoldadmin/formula)
|
38
|
-
- Django & Next.js boilerplate implementing Unfold at [github.com/unfoldadmin/turbo](https://github.com/unfoldadmin/turbo)
|
37
|
+
- **Unfold:** demo site is available at [unfoldadmin.com](https://unfoldadmin.com)
|
38
|
+
- **Formula:** repository with demo implementation at [github.com/unfoldadmin/formula](https://github.com/unfoldadmin/formula)
|
39
|
+
- **Turbo:** Django & Next.js boilerplate implementing Unfold at [github.com/unfoldadmin/turbo](https://github.com/unfoldadmin/turbo)
|
39
40
|
|
40
|
-
## Features
|
41
|
+
## Features <!-- omit from toc -->
|
41
42
|
|
42
43
|
- **Visual**: provides new user interface based on Tailwind CSS framework
|
43
44
|
- **Sidebar:** simplifies definition of custom sidebar navigation with icons
|
@@ -46,38 +47,41 @@ Unfold is theme for Django admin incorporating most common practises for buildin
|
|
46
47
|
- **Dependencies:** completely based only on `django.contrib.admin`
|
47
48
|
- **Actions:** multiple ways how to define actions within different parts of admin
|
48
49
|
- **WYSIWYG:** built-in support for WYSIWYG (Trix)
|
49
|
-
- **
|
50
|
-
- **Datetime filters:** widgets for filtering datetime values
|
50
|
+
- **Custom filters:** widgets for filtering number & datetime values
|
51
51
|
- **Dashboard:** helpers to bootstrap custom dashboard
|
52
52
|
- **Tabs:** define custom tab navigations for models
|
53
53
|
- **Colors:** possibility to override default color scheme
|
54
|
-
- **
|
54
|
+
- **Third party packages:** default support for multiple popular applications
|
55
55
|
|
56
|
-
## Table of
|
56
|
+
## Table of contents <!-- omit from toc -->
|
57
57
|
|
58
58
|
- [Installation](#installation)
|
59
59
|
- [Configuration](#configuration)
|
60
60
|
- [Available settings.py options](#available-settingspy-options)
|
61
61
|
- [Available unfold.admin.ModelAdmin options](#available-unfoldadminmodeladmin-options)
|
62
|
-
- [Decorators](#decorators)
|
63
|
-
- [@display](#display)
|
64
62
|
- [Actions](#actions)
|
65
63
|
- [Actions overview](#actions-overview)
|
66
64
|
- [Custom unfold @action decorator](#custom-unfold-action-decorator)
|
67
65
|
- [Action handler functions](#action-handler-functions)
|
68
|
-
- [For submit row action](#for-submit-row-action)
|
69
|
-
- [For global, row and detail action](#for-global-row-and-detail-action)
|
70
66
|
- [Action examples](#action-examples)
|
71
67
|
- [Filters](#filters)
|
68
|
+
- [Numeric filters](#numeric-filters)
|
69
|
+
- [Date/time filters](#datetime-filters)
|
70
|
+
- [Display decorator](#display-decorator)
|
72
71
|
- [Third party packages](#third-party-packages)
|
72
|
+
- [django-celery-beat](#django-celery-beat)
|
73
|
+
- [django-guardian](#django-guardian)
|
73
74
|
- [django-import-export](#django-import-export)
|
75
|
+
- [django-modeltranslation](#django-modeltranslation)
|
76
|
+
- [django-money](#django-money)
|
77
|
+
- [django-simple-history](#django-simple-history)
|
74
78
|
- [User Admin Form](#user-admin-form)
|
75
|
-
- [Adding
|
76
|
-
- [Project
|
77
|
-
- [Custom
|
78
|
-
- [Unfold
|
79
|
+
- [Adding custom styles and scripts](#adding-custom-styles-and-scripts)
|
80
|
+
- [Project level Tailwind stylesheet](#project-level-tailwind-stylesheet)
|
81
|
+
- [Custom admin dashboard](#custom-admin-dashboard)
|
82
|
+
- [Unfold development](#unfold-development)
|
79
83
|
- [Pre-commit](#pre-commit)
|
80
|
-
- [Poetry
|
84
|
+
- [Poetry configuration](#poetry-configuration)
|
81
85
|
- [Compiling Tailwind](#compiling-tailwind)
|
82
86
|
- [Credits](#credits)
|
83
87
|
|
@@ -93,6 +97,8 @@ INSTALLED_APPS = [
|
|
93
97
|
"unfold.contrib.filters", # optional, if special filters are needed
|
94
98
|
"unfold.contrib.forms", # optional, if special form elements are needed
|
95
99
|
"unfold.contrib.import_export", # optional, if django-import-export package is used
|
100
|
+
"unfold.contrib.guardian", # optional, if django-guardian package is used
|
101
|
+
"unfold.contrib.simple_history", # optional, if django-simple-history package is used
|
96
102
|
"django.contrib.admin", # required
|
97
103
|
]
|
98
104
|
```
|
@@ -192,6 +198,7 @@ UNFOLD = {
|
|
192
198
|
"700": "126 34 206",
|
193
199
|
"800": "107 33 168",
|
194
200
|
"900": "88 28 135",
|
201
|
+
"950": "59 7 100",
|
195
202
|
},
|
196
203
|
},
|
197
204
|
"EXTENSIONS": {
|
@@ -301,73 +308,6 @@ class CustomAdminClass(ModelAdmin):
|
|
301
308
|
}
|
302
309
|
```
|
303
310
|
|
304
|
-
## Decorators
|
305
|
-
|
306
|
-
### @display
|
307
|
-
|
308
|
-
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.
|
309
|
-
|
310
|
-
`@display(label=True)`, `@display(label={"value1": "success"})` displays a result as a label. This option fits for different types of statuses. Label can be either boolean indicating we want to use label with default color or dict where the dict is responsible for displaying labels in different colors. At the moment these color combinations are supported: success(green), info(blue), danger(red) and warning(orange).
|
311
|
-
|
312
|
-
`@display(header=True)` displays in results list two information in one table cell. Good example is when we want to display customer information, first line is going to be customer's name and right below the name display corresponding email address. Method with such a decorator is supposed to return a list with two elements `return "Full name", "E-mail address"`.
|
313
|
-
|
314
|
-
```python
|
315
|
-
# admin.py
|
316
|
-
|
317
|
-
from django.db.models import TextChoices
|
318
|
-
from django.utils.translation import gettext_lazy as _
|
319
|
-
|
320
|
-
from unfold.admin import ModelAdmin
|
321
|
-
from unfold.decorators import display
|
322
|
-
|
323
|
-
|
324
|
-
class UserStatus(TextChoices):
|
325
|
-
ACTIVE = "ACTIVE", _("Active")
|
326
|
-
PENDING = "PENDING", _("Pending")
|
327
|
-
INACTIVE = "INACTIVE", _("Inactive")
|
328
|
-
CANCELLED = "CANCELLED", _("Cancelled")
|
329
|
-
|
330
|
-
|
331
|
-
class UserAdmin(ModelAdmin):
|
332
|
-
list_display = [
|
333
|
-
"display_as_two_line_heading",
|
334
|
-
"show_status",
|
335
|
-
"show_status_with_custom_label",
|
336
|
-
]
|
337
|
-
|
338
|
-
@display(
|
339
|
-
description=_("Status"),
|
340
|
-
ordering="status",
|
341
|
-
label=True
|
342
|
-
)
|
343
|
-
def show_status_default_color(self, obj):
|
344
|
-
return obj.status
|
345
|
-
|
346
|
-
@display(
|
347
|
-
description=_("Status"),
|
348
|
-
ordering="status",
|
349
|
-
label={
|
350
|
-
UserStatus.ACTIVE: "success", # green
|
351
|
-
UserStatus.PENDING: "info", # blue
|
352
|
-
UserStatus.INACTIVE: "warning", # orange
|
353
|
-
UserStatus.CANCELLED: "danger", # red
|
354
|
-
},
|
355
|
-
)
|
356
|
-
def show_status_customized_color(self, obj)
|
357
|
-
return obj.status
|
358
|
-
|
359
|
-
@display(description=_("Status with label"), ordering="status", label=True)
|
360
|
-
def show_status_with_custom_label(self, obj):
|
361
|
-
return obj.status, obj.get_status_display()
|
362
|
-
|
363
|
-
@display(header=True)
|
364
|
-
def display_as_two_line_heading(self, obj):
|
365
|
-
"""
|
366
|
-
Third argument is short text which will appear as prefix in circle
|
367
|
-
"""
|
368
|
-
return "First main heading", "Smaller additional description", "AB"
|
369
|
-
```
|
370
|
-
|
371
311
|
## Actions
|
372
312
|
|
373
313
|
It is highly recommended to read the base [Django actions documentation](https://docs.djangoproject.com/en/4.2/ref/contrib/admin/actions/) before reading this section, since Unfold actions are derived from Django actions.
|
@@ -398,13 +338,13 @@ Unfold also uses custom `@action` decorator, supporting 2 more parameters in com
|
|
398
338
|
This section provides explanation of how the action handler functions should be constructed for Unfold actions.
|
399
339
|
For default actions, follow official Django admin documentation.
|
400
340
|
|
401
|
-
#### For submit row action
|
341
|
+
#### For submit row action <!-- omit from toc -->
|
402
342
|
|
403
343
|
Submit row actions work a bit differently when compared to other custom Unfold actions.
|
404
344
|
These actions first invoke form save (same as if you hit `Save` button) and then lets you
|
405
345
|
perform additional logic on already saved instance.
|
406
346
|
|
407
|
-
#### For global, row and detail action
|
347
|
+
#### For global, row and detail action <!-- omit from toc -->
|
408
348
|
|
409
349
|
All these actions are based on custom URLs generated for each of them. Handler function for these views is
|
410
350
|
basically function based view.
|
@@ -502,6 +442,10 @@ class UserAdmin(ModelAdmin):
|
|
502
442
|
|
503
443
|
By default, Django admin handles all filters as regular HTML links pointing at the same URL with different query parameters. This approach is for basic filtering more than enough. In the case of more advanced filtering by incorporating input fields, it is not going to work.
|
504
444
|
|
445
|
+
**Note:** when implementing a filter which contains input fields, there is a no way that user can submit the values, because default filters does not contain submit button. To implement submit button, `unfold.admin.ModelAdmin` contains boolean `list_filter_submit` flag which enables submit button in filter form.
|
446
|
+
|
447
|
+
### Numeric filters
|
448
|
+
|
505
449
|
Currently, Unfold implements numeric filters inside `unfold.contrib.filters` application. In order to use these filters, it is required to add this application into `INSTALLED_APPS` in `settings.py` right after `unfold` application.
|
506
450
|
|
507
451
|
```python
|
@@ -516,8 +460,6 @@ from unfold.contrib.filters.admin import (
|
|
516
460
|
RangeNumericFilter,
|
517
461
|
SingleNumericFilter,
|
518
462
|
SliderNumericFilter,
|
519
|
-
RangeDateFilter,
|
520
|
-
RangeDateTimeFilter,
|
521
463
|
)
|
522
464
|
|
523
465
|
|
@@ -539,8 +481,6 @@ class YourModelAdmin(ModelAdmin):
|
|
539
481
|
("field_B", RangeNumericFilter), # Numeric range search, __gte and __lte lookup
|
540
482
|
("field_C", SliderNumericFilter), # Numeric range filter but with slider
|
541
483
|
("field_D", CustomSliderNumericFilter), # Numeric filter with custom attributes
|
542
|
-
("field_E", RangeDateFilter), # Date filter
|
543
|
-
("field_F", RangeDateTimeFilter), # Datetime filter
|
544
484
|
CustomRangeNumericListFilter, # Numeric range search not restricted to a model field
|
545
485
|
)
|
546
486
|
|
@@ -548,13 +488,150 @@ class YourModelAdmin(ModelAdmin):
|
|
548
488
|
return super().get_queryset().annotate(items_count=Count("item", distinct=True))
|
549
489
|
```
|
550
490
|
|
491
|
+
### Date/time filters
|
492
|
+
|
493
|
+
```python
|
494
|
+
# admin.py
|
495
|
+
|
496
|
+
from django.contrib import admin
|
497
|
+
from django.contrib.auth.models import User
|
498
|
+
|
499
|
+
from unfold.admin import ModelAdmin
|
500
|
+
from unfold.contrib.filters.admin import (
|
501
|
+
RangeDateFilter,
|
502
|
+
RangeDateTimeFilter,
|
503
|
+
)
|
504
|
+
|
505
|
+
|
506
|
+
@admin.register(User)
|
507
|
+
class YourModelAdmin(ModelAdmin):
|
508
|
+
list_filter_submit = True # Submit button at the bottom of the filter
|
509
|
+
list_filter = (
|
510
|
+
("field_E", RangeDateFilter), # Date filter
|
511
|
+
("field_F", RangeDateTimeFilter), # Datetime filter
|
512
|
+
)
|
513
|
+
```
|
514
|
+
|
515
|
+
## Display decorator
|
516
|
+
|
517
|
+
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.
|
518
|
+
|
519
|
+
`@display(label=True)`, `@display(label={"value1": "success"})` displays a result as a label. This option fits for different types of statuses. Label can be either boolean indicating we want to use label with default color or dict where the dict is responsible for displaying labels in different colors. At the moment these color combinations are supported: success(green), info(blue), danger(red) and warning(orange).
|
520
|
+
|
521
|
+
`@display(header=True)` displays in results list two information in one table cell. Good example is when we want to display customer information, first line is going to be customer's name and right below the name display corresponding email address. Method with such a decorator is supposed to return a list with two elements `return "Full name", "E-mail address"`. There is a third optional argument, which is type of the string and its value is displayed in a circle before first two values on the front end. Its optimal usage is for displaying initials.
|
522
|
+
|
523
|
+
```python
|
524
|
+
# admin.py
|
525
|
+
|
526
|
+
from django.db.models import TextChoices
|
527
|
+
from django.utils.translation import gettext_lazy as _
|
528
|
+
|
529
|
+
from unfold.admin import ModelAdmin
|
530
|
+
from unfold.decorators import display
|
531
|
+
|
532
|
+
|
533
|
+
class UserStatus(TextChoices):
|
534
|
+
ACTIVE = "ACTIVE", _("Active")
|
535
|
+
PENDING = "PENDING", _("Pending")
|
536
|
+
INACTIVE = "INACTIVE", _("Inactive")
|
537
|
+
CANCELLED = "CANCELLED", _("Cancelled")
|
538
|
+
|
539
|
+
|
540
|
+
class UserAdmin(ModelAdmin):
|
541
|
+
list_display = [
|
542
|
+
"display_as_two_line_heading",
|
543
|
+
"show_status",
|
544
|
+
"show_status_with_custom_label",
|
545
|
+
]
|
546
|
+
|
547
|
+
@display(
|
548
|
+
description=_("Status"),
|
549
|
+
ordering="status",
|
550
|
+
label=True
|
551
|
+
)
|
552
|
+
def show_status_default_color(self, obj):
|
553
|
+
return obj.status
|
554
|
+
|
555
|
+
@display(
|
556
|
+
description=_("Status"),
|
557
|
+
ordering="status",
|
558
|
+
label={
|
559
|
+
UserStatus.ACTIVE: "success", # green
|
560
|
+
UserStatus.PENDING: "info", # blue
|
561
|
+
UserStatus.INACTIVE: "warning", # orange
|
562
|
+
UserStatus.CANCELLED: "danger", # red
|
563
|
+
},
|
564
|
+
)
|
565
|
+
def show_status_customized_color(self, obj)
|
566
|
+
return obj.status
|
567
|
+
|
568
|
+
@display(description=_("Status with label"), ordering="status", label=True)
|
569
|
+
def show_status_with_custom_label(self, obj):
|
570
|
+
return obj.status, obj.get_status_display()
|
571
|
+
|
572
|
+
@display(header=True)
|
573
|
+
def display_as_two_line_heading(self, obj):
|
574
|
+
"""
|
575
|
+
Third argument is short text which will appear as prefix in circle
|
576
|
+
"""
|
577
|
+
return "First main heading", "Smaller additional description", "AB"
|
578
|
+
```
|
579
|
+
|
551
580
|
## Third party packages
|
552
581
|
|
553
|
-
### django-
|
582
|
+
### django-celery-beat
|
583
|
+
|
584
|
+
In general, django-celery-beat does not have any components that require special styling. The default changelist templates are not inheriting from Unfold's `ModelAdmin` but they are using default `ModelAdmin` coming from `django.contrib.admin` which is causing some design discrepancies in the changelist.
|
585
|
+
|
586
|
+
In the source code below you can find a short code snippet to unregister all `django-celery-beat` admin classes and register them with the proper parent `ModelAdmin` class.
|
587
|
+
|
588
|
+
```python
|
589
|
+
# admin.py
|
590
|
+
from django.contrib import admin
|
591
|
+
from unfold.admin import ModelAdmin
|
592
|
+
|
593
|
+
from django_celery_beat.models import (
|
594
|
+
ClockedSchedule,
|
595
|
+
CrontabSchedule,
|
596
|
+
IntervalSchedule,
|
597
|
+
PeriodicTask,
|
598
|
+
SolarSchedule,
|
599
|
+
)
|
600
|
+
|
601
|
+
|
602
|
+
admin.site.unregister(PeriodicTask)
|
603
|
+
admin.site.unregister(IntervalSchedule)
|
604
|
+
admin.site.unregister(CrontabSchedule)
|
605
|
+
admin.site.unregister(SolarSchedule)
|
606
|
+
admin.site.unregister(ClockedSchedule)
|
607
|
+
|
608
|
+
@admin.register(PeriodicTask)
|
609
|
+
class PeriodicTaskAdmin(ModelAdmin):
|
610
|
+
pass
|
611
|
+
|
612
|
+
|
613
|
+
@admin.register(IntervalSchedule)
|
614
|
+
class IntervalScheduleAdmin(ModelAdmin):
|
615
|
+
pass
|
616
|
+
|
617
|
+
|
618
|
+
@admin.register(CrontabSchedule)
|
619
|
+
class CrontabScheduleAdmin(ModelAdmin):
|
620
|
+
pass
|
621
|
+
|
622
|
+
|
623
|
+
@admin.register(SolarSchedule)
|
624
|
+
class SolarScheduleAdmin(ModelAdmin):
|
625
|
+
pass
|
626
|
+
```
|
627
|
+
|
628
|
+
### django-guardian
|
554
629
|
|
555
|
-
|
630
|
+
Adding support for django-guardian is quote straightforward in Unfold, just add `unfold.contrib.guardian` to `INSTALLED_APPS` at the beggining of the file. This action will override all templates coming from the django-guardian. Please note that **Object permissions** link is available in top right dropdown navigation.
|
556
631
|
|
557
|
-
|
632
|
+
### django-import-export
|
633
|
+
|
634
|
+
1. Add `unfold.contrib.import_export` to `INSTALLED_APPS` at the beggining of the file. This action will override all templates coming from the application.
|
558
635
|
2. Change `import_form_class` and `export_form_class` in ModelAdmin which is inheriting from `ImportExportModelAdmin`. This chunk of code is responsible for adding proper styling to form elements.
|
559
636
|
|
560
637
|
```python
|
@@ -568,6 +645,36 @@ class ExampleAdmin(ModelAdmin, ImportExportModelAdmin):
|
|
568
645
|
export_form_class = ExportForm
|
569
646
|
```
|
570
647
|
|
648
|
+
### django-modeltranslation
|
649
|
+
|
650
|
+
By default Unfold does not contain any specific implementation for django-modeltranslation and the application is partially supported. Basic behavior is supported except of tab navigation provided by django-modeltranslation. At the moment there are no plans in supporting this behavior.
|
651
|
+
|
652
|
+
For django-modeltranslation fields for spefic languages, it is possible to define custom flags which will appear as a suffix in field's label. It is recommended to use emojis as suffix.
|
653
|
+
|
654
|
+
```python
|
655
|
+
# settings.py
|
656
|
+
|
657
|
+
UNFOLD = {
|
658
|
+
"EXTENSIONS": {
|
659
|
+
"modeltranslation": {
|
660
|
+
"flags": {
|
661
|
+
"en": "🇬🇧",
|
662
|
+
"fr": "🇫🇷",
|
663
|
+
"nl": "🇧🇪",
|
664
|
+
},
|
665
|
+
},
|
666
|
+
},
|
667
|
+
}
|
668
|
+
```
|
669
|
+
|
670
|
+
### django-money
|
671
|
+
|
672
|
+
This application is supported in Unfold by default. It is not needed to add any other applications into `INSTALLED_APPS`. Unfold is recognizing special form widget coming from django-money and applying specific styling.
|
673
|
+
|
674
|
+
### django-simple-history
|
675
|
+
|
676
|
+
To make this application work, add `unfold.contrib.simple_history` into `settings.py` in `INSTALLED_APPS` variable before right after `unfold`. This app should ensure that templates coming from django-simple-history are overriden by Unfold.
|
677
|
+
|
571
678
|
## User Admin Form
|
572
679
|
|
573
680
|
User's admin in Django is specific as it contains several forms which are requiring custom styling. All of these forms has been inherited and accordingly adjusted. In user admin class it is needed to use these inherited form classes to enable custom styling matching rest of the website.
|
@@ -590,7 +697,7 @@ class UserAdmin(BaseUserAdmin, ModelAdmin):
|
|
590
697
|
change_password_form = AdminPasswordChangeForm
|
591
698
|
```
|
592
699
|
|
593
|
-
## Adding
|
700
|
+
## Adding custom styles and scripts
|
594
701
|
|
595
702
|
To add new custom styles, for example for custom dashboard, it is possible to load them via **STYLES** key in **UNFOLD** dict. This key accepts a list of strings or lambda functions which will be loaded on all pages. JavaScript files can be loaded by using similar apprach, but **SCRIPTS** is used.
|
596
703
|
|
@@ -609,7 +716,7 @@ UNFOLD = {
|
|
609
716
|
}
|
610
717
|
```
|
611
718
|
|
612
|
-
## Project
|
719
|
+
## Project level Tailwind stylesheet
|
613
720
|
|
614
721
|
When creating custom dashboard or adding custom components, it is needed to add own styles. Adding custom styles is described above. Most of the time, it is supposed that new elements are going to match with the rest of the administration panel. First of all, create tailwind.config.js in your application. Below is located minimal configuration for this file.
|
615
722
|
|
@@ -642,7 +749,7 @@ Once the configuration file is set, it is possible to compile new styles which c
|
|
642
749
|
npx tailwindcss -o your_project/static/css/styles.css --watch --minify
|
643
750
|
```
|
644
751
|
|
645
|
-
## Custom
|
752
|
+
## Custom admin dashboard
|
646
753
|
|
647
754
|
The most common thing which needs to be adjusted for each project in admin is the dashboard. By default Unfold does not provide any dashboard components. The default dashboard experience with list of all applications and models is kept with proper styling matching rest of the components but thats it. Anyway, Unfold was created that creation of custom dashboard will be streamlined.
|
648
755
|
|
@@ -668,7 +775,7 @@ Create `templates/admin/index.html` in your project and paste the base template
|
|
668
775
|
|
669
776
|
Note: In case that it is needed to pass custom variables into dashboard tamplate, check **DASHOARD_CALLBACK** in **UNFOLD** dict.
|
670
777
|
|
671
|
-
## Unfold
|
778
|
+
## Unfold development
|
672
779
|
|
673
780
|
### Pre-commit
|
674
781
|
|
@@ -680,7 +787,7 @@ pre-commit install
|
|
680
787
|
pre-commit install --hook-type commit-msg
|
681
788
|
```
|
682
789
|
|
683
|
-
### Poetry
|
790
|
+
### Poetry configuration
|
684
791
|
|
685
792
|
To add a new feature or fix the easiest approach is to use django-unfold in combination with Poetry. The process looks like:
|
686
793
|
|
@@ -703,9 +810,9 @@ npm run tailwind:build # run once
|
|
703
810
|
|
704
811
|
Some components like datepickers, calendars or selectors in admin was not possible to style by overriding html templates so their default styles are overriden in **styles.css**.
|
705
812
|
|
706
|
-
|
813
|
+
**Note:** most of the custom styles located in style.css are created via `@apply some-tailwind-class;` as is not possible to manually add CSS class to element which are for example created via jQuery.
|
707
814
|
|
708
|
-
|
815
|
+
## Credits
|
709
816
|
|
710
817
|
- [TailwindCSS](https://tailwindcss.com/) - CSS framework
|
711
818
|
- [HTMX](https://htmx.org/) - AJAX communication with backend
|