django-unfold 0.30.0__tar.gz → 0.32.0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (208) hide show
  1. {django_unfold-0.30.0 → django_unfold-0.32.0}/PKG-INFO +101 -31
  2. {django_unfold-0.30.0 → django_unfold-0.32.0}/README.md +100 -30
  3. {django_unfold-0.30.0 → django_unfold-0.32.0}/pyproject.toml +1 -1
  4. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/admin.py +30 -11
  5. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html +3 -3
  6. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/forms/templates/unfold/forms/array.html +3 -1
  7. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/forms/templates/unfold/forms/helpers/toolbar.html +6 -6
  8. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/forms/templates/unfold/forms/wysiwyg.html +1 -1
  9. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/forms/widgets.py +22 -11
  10. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/guardian/templates/unfold/guardian/group_form.html +4 -4
  11. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/guardian/templates/unfold/guardian/user_form.html +4 -4
  12. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_form.html +1 -1
  13. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_errors.html +1 -1
  14. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_preview.html +3 -3
  15. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_validation.html +4 -4
  16. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/inlines/forms.py +1 -2
  17. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/simple_history/templates/simple_history/object_history_list.html +9 -9
  18. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/simple_history/templates/simple_history/submit_line.html +1 -1
  19. django_unfold-0.32.0/src/unfold/dataclasses.py +22 -0
  20. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/fields.py +1 -1
  21. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/settings.py +1 -0
  22. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/sites.py +39 -15
  23. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/css/styles.css +1 -1
  24. django_unfold-0.32.0/src/unfold/static/unfold/js/alpine.anchor.js +1 -0
  25. django_unfold-0.32.0/src/unfold/static/unfold/js/alpine.js +5 -0
  26. django_unfold-0.32.0/src/unfold/static/unfold/js/alpine.persist.js +1 -0
  27. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/js/app.js +26 -3
  28. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/styles.css +10 -10
  29. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/actions.html +1 -1
  30. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/app_list.html +1 -1
  31. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/base.html +4 -4
  32. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/change_list.html +2 -2
  33. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/change_list_results.html +2 -2
  34. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/delete_confirmation.html +4 -4
  35. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/delete_selected_confirmation.html +4 -4
  36. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/edit_inline/stacked.html +2 -2
  37. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/edit_inline/tabular.html +3 -3
  38. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/filter.html +2 -2
  39. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/includes/fieldset.html +1 -1
  40. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/includes/object_delete_summary.html +1 -1
  41. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/login.html +8 -8
  42. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/object_history.html +4 -4
  43. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/search_form.html +1 -1
  44. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/submit_line.html +7 -5
  45. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/auth/widgets/read_only_password_hash.html +1 -1
  46. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/registration/logged_out.html +1 -1
  47. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/change_list_filter.html +9 -1
  48. django_unfold-0.32.0/src/unfold/templates/unfold/components/card.html +27 -0
  49. django_unfold-0.32.0/src/unfold/templates/unfold/components/icon.html +1 -0
  50. django_unfold-0.32.0/src/unfold/templates/unfold/components/separator.html +1 -0
  51. django_unfold-0.32.0/src/unfold/templates/unfold/components/table.html +31 -0
  52. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/account_links.html +2 -2
  53. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/actions_row.html +4 -4
  54. django_unfold-0.32.0/src/unfold/templates/unfold/helpers/app_list.html +99 -0
  55. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/app_list_default.html +4 -4
  56. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/breadcrumb_item.html +1 -1
  57. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/field_readonly_value.html +1 -1
  58. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/fieldset_row.html +6 -6
  59. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/fieldsets_tabs.html +2 -2
  60. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/header.html +1 -1
  61. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/help_text.html +1 -1
  62. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/history.html +1 -1
  63. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/label.html +2 -3
  64. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/search.html +7 -4
  65. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/search_results.html +2 -2
  66. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/tab_action.html +1 -1
  67. django_unfold-0.32.0/src/unfold/templates/unfold/helpers/tab_list.html +62 -0
  68. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/theme_switch.html +2 -2
  69. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/layouts/skeleton.html +6 -1
  70. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/clearable_file_input.html +14 -6
  71. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/clearable_file_input_small.html +4 -4
  72. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/split_datetime.html +2 -2
  73. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templatetags/unfold.py +33 -12
  74. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templatetags/unfold_list.py +16 -6
  75. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/widgets.py +2 -2
  76. django_unfold-0.30.0/src/unfold/dataclasses.py +0 -13
  77. django_unfold-0.30.0/src/unfold/static/unfold/js/alpine.js +0 -5
  78. django_unfold-0.30.0/src/unfold/static/unfold/js/alpine.persist.js +0 -1
  79. django_unfold-0.30.0/src/unfold/templates/unfold/components/card.html +0 -23
  80. django_unfold-0.30.0/src/unfold/templates/unfold/components/separator.html +0 -1
  81. django_unfold-0.30.0/src/unfold/templates/unfold/helpers/app_list.html +0 -89
  82. django_unfold-0.30.0/src/unfold/templates/unfold/helpers/tab_list.html +0 -40
  83. {django_unfold-0.30.0 → django_unfold-0.32.0}/LICENSE.md +0 -0
  84. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/__init__.py +0 -0
  85. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/apps.py +0 -0
  86. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/checks.py +0 -0
  87. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/__init__.py +0 -0
  88. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/__init__.py +0 -0
  89. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/admin.py +0 -0
  90. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/apps.py +0 -0
  91. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/forms.py +0 -0
  92. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/static/unfold/filters/css/nouislider.min.css +0 -0
  93. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/static/unfold/filters/js/DateTimeShortcuts.js +0 -0
  94. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/static/unfold/filters/js/admin-numeric-filter.js +0 -0
  95. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/static/unfold/filters/js/nouislider.min.js +0 -0
  96. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/static/unfold/filters/js/wNumb.min.js +0 -0
  97. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_date_range.html +0 -0
  98. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_datetime_range.html +0 -0
  99. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_field.html +0 -0
  100. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_range.html +0 -0
  101. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_single.html +0 -0
  102. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/forms/__init__.py +0 -0
  103. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/forms/apps.py +0 -0
  104. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/forms/static/unfold/forms/css/trix.css +0 -0
  105. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix.config.js +0 -0
  106. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix.js +0 -0
  107. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/guardian/__init__.py +0 -0
  108. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/guardian/apps.py +0 -0
  109. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/change_form.html +0 -0
  110. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/field.html +0 -0
  111. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage.html +0 -0
  112. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_group.html +0 -0
  113. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_user.html +0 -0
  114. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/__init__.py +0 -0
  115. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/apps.py +0 -0
  116. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/forms.py +0 -0
  117. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/base.html +0 -0
  118. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_export.html +0 -0
  119. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_export_item.html +0 -0
  120. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import_export.html +0 -0
  121. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import_item.html +0 -0
  122. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/export.html +0 -0
  123. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/import.html +0 -0
  124. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_confirm.html +0 -0
  125. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_form.html +0 -0
  126. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/import_export/templates/admin/import_export/resource_fields_list.html +0 -0
  127. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/inlines/__init__.py +0 -0
  128. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/inlines/admin.py +0 -0
  129. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/inlines/apps.py +0 -0
  130. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/inlines/checks.py +0 -0
  131. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/simple_history/__init__.py +0 -0
  132. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/simple_history/apps.py +0 -0
  133. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/simple_history/templates/simple_history/object_history.html +0 -0
  134. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/contrib/simple_history/templates/simple_history/object_history_form.html +0 -0
  135. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/decorators.py +0 -0
  136. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/exceptions.py +0 -0
  137. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/forms.py +0 -0
  138. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/css/simplebar.css +0 -0
  139. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/fonts/inter/Inter-Bold.woff2 +0 -0
  140. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/fonts/inter/Inter-Medium.woff2 +0 -0
  141. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/fonts/inter/Inter-Regular.woff2 +0 -0
  142. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/fonts/inter/Inter-SemiBold.woff2 +0 -0
  143. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/fonts/inter/styles.css +0 -0
  144. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/fonts/material-symbols/Material-Symbols-Outlined.woff2 +0 -0
  145. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/fonts/material-symbols/styles.css +0 -0
  146. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/js/chart.js +0 -0
  147. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/js/htmx.js +0 -0
  148. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/static/unfold/js/simplebar.js +0 -0
  149. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/app_index.html +0 -0
  150. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/auth/user/add_form.html +0 -0
  151. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/auth/user/change_password.html +0 -0
  152. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/base_site.html +0 -0
  153. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/change_form.html +0 -0
  154. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/change_form_object_tools.html +0 -0
  155. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/change_list_object_tools.html +0 -0
  156. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/date_hierarchy.html +0 -0
  157. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/index.html +0 -0
  158. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/nav_sidebar.html +0 -0
  159. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/admin/pagination.html +0 -0
  160. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/registration/password_change_done.html +0 -0
  161. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/registration/password_change_form.html +0 -0
  162. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/components/button.html +0 -0
  163. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/components/chart/bar.html +0 -0
  164. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/components/chart/line.html +0 -0
  165. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/components/container.html +0 -0
  166. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/components/flex.html +0 -0
  167. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/components/navigation.html +0 -0
  168. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/components/progress.html +0 -0
  169. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/components/text.html +0 -0
  170. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/components/title.html +0 -0
  171. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/add_link.html +0 -0
  172. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/attrs.html +0 -0
  173. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/boolean.html +0 -0
  174. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/display_header.html +0 -0
  175. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/display_label.html +0 -0
  176. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/field.html +0 -0
  177. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/field_readonly.html +0 -0
  178. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/form_errors.html +0 -0
  179. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/form_label.html +0 -0
  180. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/messages/error.html +0 -0
  181. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/messages/errornote.html +0 -0
  182. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/messages/info.html +0 -0
  183. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/messages.html +0 -0
  184. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/navigation.html +0 -0
  185. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/pagination_current_item.html +0 -0
  186. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/pagination_ellipsis.html +0 -0
  187. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/site_icon.html +0 -0
  188. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/site_logo.html +0 -0
  189. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/submit.html +0 -0
  190. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/userlinks.html +0 -0
  191. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/helpers/welcomemsg.html +0 -0
  192. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/layouts/base.html +0 -0
  193. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/layouts/base_simple.html +0 -0
  194. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/date.html +0 -0
  195. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/foreign_key_raw_id.html +0 -0
  196. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/radio.html +0 -0
  197. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/radio_option.html +0 -0
  198. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/range.html +0 -0
  199. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/related_widget_wrapper.html +0 -0
  200. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/split_datetime_vertical.html +0 -0
  201. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/split_money.html +0 -0
  202. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/textarea.html +0 -0
  203. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/textarea_expandable.html +0 -0
  204. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templates/unfold/widgets/time.html +0 -0
  205. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/templatetags/__init__.py +0 -0
  206. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/typing.py +0 -0
  207. {django_unfold-0.30.0 → django_unfold-0.32.0}/src/unfold/utils.py +0 -0
  208. {django_unfold-0.30.0 → django_unfold-0.32.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.30.0
3
+ Version: 0.32.0
4
4
  Summary: Modern Django admin theme for seamless interface development
5
5
  Home-page: https://unfoldadmin.com
6
6
  License: MIT
@@ -33,7 +33,7 @@ Description-Content-Type: text/markdown
33
33
  ![Code Style - Ruff](https://img.shields.io/badge/code%20style-ruff-30173D.svg?style=for-the-badge)
34
34
  ![Pre Commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge)
35
35
 
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.
36
+ Unfold is a theme for Django admin incorporating most common practices for building full-fledged admin areas. It is designed to work on top of default administration provided by Django.
37
37
 
38
38
  - **Unfold:** demo site is available at [unfoldadmin.com](https://unfoldadmin.com?utm_medium=github&utm_source=unfold)
39
39
  - **Formula:** repository with demo implementation at [github.com/unfoldadmin/formula](https://github.com/unfoldadmin/formula)
@@ -45,7 +45,7 @@ Did you decide to start using Unfold but you don't have time to make the switch
45
45
 
46
46
  ## Features <!-- omit from toc -->
47
47
 
48
- - **Visual**: provides new user interface based on Tailwind CSS framework
48
+ - **Visual**: provides a new user interface based on Tailwind CSS framework
49
49
  - **Sidebar:** simplifies definition of custom sidebar navigation with icons
50
50
  - **Dark mode:** supports both light and dark mode versions
51
51
  - **Configuration:** most of the basic options can be changed in settings.py
@@ -55,14 +55,16 @@ Did you decide to start using Unfold but you don't have time to make the switch
55
55
  - **Array widget:** built-in widget for `django.contrib.postgres.fields.ArrayField`
56
56
  - **Filters:** custom dropdown, numeric, datetime, and text fields
57
57
  - **Dashboard:** custom components for rapid dashboard development
58
+ - **Inline tabs:** group inlines into tab navigation in the change form
58
59
  - **Model tabs:** define custom tab navigations for models
59
- - **Fieldset tabs:** merge several fielsets into tabs in change form
60
- - **Colors:** possibility to override default color scheme
61
- - **Changeform modes:** display fields in changeform in compressed mode
60
+ - **Fieldset tabs:** merge several fieldsets into tabs in the change form
61
+ - **Colors:** possibility to override the default color scheme
62
+ - **Changeform modes:** display fields in the change form in compressed mode
62
63
  - **Third party packages:** default support for multiple popular applications
63
64
  - **Environment label**: distinguish between environments by displaying a label
64
65
  - **Nonrelated inlines**: displays nonrelated model as inline in changeform
65
66
  - **Parallel admin**: support for default admin in parallel with Unfold. [Admin migration guide](https://unfoldadmin.com/blog/migrating-django-admin-unfold/?utm_medium=github&utm_source=unfold)
67
+ - **Favicons**: built-in support for configuring various site favicons
66
68
  - **VS Code**: project configuration and development container is included
67
69
 
68
70
  ## Table of contents <!-- omit from toc -->
@@ -100,6 +102,7 @@ Did you decide to start using Unfold but you don't have time to make the switch
100
102
  - [Overriding template](#overriding-template)
101
103
  - [Custom variables](#custom-variables)
102
104
  - [Unfold components](#unfold-components)
105
+ - [Table component example](#table-component-example)
103
106
  - [Unfold development](#unfold-development)
104
107
  - [Pre-commit](#pre-commit)
105
108
  - [Poetry configuration](#poetry-configuration)
@@ -111,7 +114,7 @@ Did you decide to start using Unfold but you don't have time to make the switch
111
114
 
112
115
  ## Installation
113
116
 
114
- The installation process is minimal. Everything what is needed after installation is to put new application at the beginning of **INSTALLED_APPS**. Default admin configuration in urls.py can stay as it is and there are no changes required.
117
+ The installation process is minimal. Everything that is needed after installation is to put new application at the beginning of **INSTALLED_APPS**. The default admin configuration in urls.py can stay as it is, and no changes are required.
115
118
 
116
119
  ```python
117
120
  # settings.py
@@ -170,17 +173,24 @@ class CustomAdminClass(ModelAdmin):
170
173
 
171
174
  from django.contrib import admin
172
175
  from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
176
+ from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
173
177
  from django.contrib.auth.models import User
174
178
 
175
179
  from unfold.admin import ModelAdmin
176
180
 
177
181
 
178
182
  admin.site.unregister(User)
183
+ admin.site.unregister(Group)
179
184
 
180
185
 
181
186
  @admin.register(User)
182
187
  class UserAdmin(BaseUserAdmin, ModelAdmin):
183
188
  pass
189
+
190
+
191
+ @admin.register(Group)
192
+ class GroupAdmin(BaseGroupAdmin, ModelAdmin):
193
+ pass
184
194
  ```
185
195
 
186
196
  ## Configuration
@@ -209,6 +219,14 @@ UNFOLD = {
209
219
  "dark": lambda request: static("logo-dark.svg"), # dark mode
210
220
  },
211
221
  "SITE_SYMBOL": "speed", # symbol from icon set
222
+ "SITE_FAVICONS": [
223
+ {
224
+ "rel": "icon",
225
+ "sizes": "32x32",
226
+ "type": "image/svg+xml",
227
+ "href": lambda request: static("favicon.svg"),
228
+ },
229
+ ],
212
230
  "SHOW_HISTORY": True, # show/hide "History" button, default: True
213
231
  "SHOW_VIEW_ON_SITE": True, # show/hide "View on site" button, default: True
214
232
  "ENVIRONMENT": "sample_app.environment_callback",
@@ -255,6 +273,7 @@ UNFOLD = {
255
273
  {
256
274
  "title": _("Navigation"),
257
275
  "separator": True, # Top border
276
+ "collapsible": True, # Collapsible group of links
258
277
  "items": [
259
278
  {
260
279
  "title": _("Dashboard"),
@@ -345,6 +364,9 @@ class CustomAdminClass(ModelAdmin):
345
364
  # Display submit button in filters
346
365
  list_filter_submit = False
347
366
 
367
+ # Display changelist in fullwidth
368
+ list_fullwidth = False
369
+
348
370
  # Position horizontal scrollbar in changelist at the top
349
371
  list_horizontal_scrollbar_top = False
350
372
 
@@ -441,7 +463,7 @@ class UserAdmin(ModelAdmin):
441
463
  actions_detail = ["change_detail_action_block"]
442
464
  actions_submit_line = ["submit_line_action_activate"]
443
465
 
444
- @action(description=_("Save & Activate"))
466
+ @action(description=_("Save & Activate"), permissions=["submit_line_action_activate"])
445
467
  def submit_line_action_activate(self, request: HttpRequest, obj: User):
446
468
  """
447
469
  If instance is modified in any way, it also needs to be saved,
@@ -453,6 +475,9 @@ class UserAdmin(ModelAdmin):
453
475
  obj.is_active = True
454
476
  obj.save()
455
477
 
478
+ def has_submit_line_action_activate_permission(self, request: HttpRequest, object_id: Union[str, int]):
479
+ pass
480
+
456
481
  @action(description=_("Import"), url_path="import")
457
482
  def changelist_global_action_import(self, request: HttpRequest):
458
483
  """
@@ -477,7 +502,7 @@ class UserAdmin(ModelAdmin):
477
502
  """
478
503
  return redirect(f"https://example.com/{object_id}")
479
504
 
480
- @action(description=_("Detail"), url_path="detail-action", attrs={"target": "_blank"})
505
+ @action(description=_("Detail"), url_path="detail-action", attrs={"target": "_blank"}, permissions=["change_detail_action_block"])
481
506
  def change_detail_action_block(self, request: HttpRequest, object_id: int):
482
507
  """
483
508
  Handler for detail action.
@@ -492,6 +517,10 @@ class UserAdmin(ModelAdmin):
492
517
  return redirect(
493
518
  reverse_lazy("admin:users_user_change", args=(object_id,))
494
519
  )
520
+
521
+
522
+ def has_change_detail_action_block_permission(self, request: HttpRequest, object_id: Union[str, int]):
523
+ pass
495
524
  ```
496
525
 
497
526
  ### Action with form example
@@ -563,7 +592,7 @@ Text input field which allows filtering by the free string submitted by the user
563
592
 
564
593
  `FieldTextFilter` requires just a model field name and the filter will make `__icontains` search on this field. There are no other things to configure so the integration in `list_filter` will be just one new row looking like `("model_field_name", FieldTextFilter)`.
565
594
 
566
- In the case of the `TextFilter`, it is needed the write a whole new class inheriting from `TextFilter` with a custom implementation of the `queryset` method and the `parameter_name` attribute. This attribute will be a representation of the search query parameter name in URI. The benefit of the `TextFilter` is the possibility of writing complex queries.
595
+ In the case of the `TextFilter`, it is needed to write a whole new class inheriting from `TextFilter` with a custom implementation of the `queryset` method and the `parameter_name` attribute. This attribute will be a representation of the search query parameter name in URI. The benefit of the `TextFilter` is the possibility of writing complex queries.
567
596
 
568
597
  ```python
569
598
  from django.contrib import admin
@@ -598,7 +627,7 @@ class MyAdmin(ModelAdmin):
598
627
 
599
628
  Dropdown filters will display a select field with a list of options. Unfold contains two types of dropdowns: `ChoicesDropdownFilter` and `RelatedDropdownFilter`.
600
629
 
601
- The difference between them is that `ChoicesDropdownFilter` will collect a list of options based on the `choices` attribute of the model field so most commonly it will be used in combination with `CharField` with specified `choices`. On the other side, `RelatedDropdownFilter` needs a one-to-many or many-to-many foreign key to display options.
630
+ The difference between them is that `ChoicesDropdownFilter` will collect a list of options based on the `choices` attribute of the model field so most commonly it will be used in combination with `CharField` with specified `choices`. On the other hand, `RelatedDropdownFilter` needs a one-to-many or many-to-many foreign key to display options.
602
631
 
603
632
  **Note:** At the moment Unfold does not implement a dropdown with an autocomplete functionality, so it is important not to use dropdowns displaying large datasets.
604
633
 
@@ -907,6 +936,19 @@ class MyModelAdmin(ModelAdmin):
907
936
  )
908
937
  ```
909
938
 
939
+ Inlines can be grouped into tab navigation by specifying `tab` attribute in the inline class.
940
+
941
+ ```python
942
+ # admin.py
943
+
944
+ from unfold.admin import TabularInline
945
+
946
+
947
+ class MyInline(TabularInline):
948
+ model = User
949
+ tab = True
950
+ ```
951
+
910
952
  ## Third party packages
911
953
 
912
954
  ### django-celery-beat
@@ -976,11 +1018,11 @@ class ClockedScheduleAdmin(BaseClockedScheduleAdmin, ModelAdmin):
976
1018
 
977
1019
  ### django-guardian
978
1020
 
979
- 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.
1021
+ Adding support for django-guardian is quite straightforward in Unfold, just add `unfold.contrib.guardian` to `INSTALLED_APPS` at the beginning 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.
980
1022
 
981
1023
  ### django-import-export
982
1024
 
983
- 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.
1025
+ 1. Add `unfold.contrib.import_export` to `INSTALLED_APPS` at the beginning of the file. This action will override all templates coming from the application.
984
1026
  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.
985
1027
 
986
1028
  ```python
@@ -1052,7 +1094,7 @@ This application is supported in Unfold by default. It is not needed to add any
1052
1094
 
1053
1095
  ### django-simple-history
1054
1096
 
1055
- 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.
1097
+ 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 overridden by Unfold.
1056
1098
 
1057
1099
  ## User Admin Form
1058
1100
 
@@ -1133,7 +1175,7 @@ npx tailwindcss -o your_project/static/css/styles.css --watch --minify
1133
1175
 
1134
1176
  ### Overriding template
1135
1177
 
1136
- Create `templates/admin/index.html` in your project and paste the base template below into it. By default, all your custom styles here are not compiled because CSS classes are located in your specific project. Here it is needed to set up the Tailwind for your project and all requried instructions are located in [Project Level Tailwind Stylesheet](#project-level-tailwind-stylesheet) chapter.
1178
+ Create `templates/admin/index.html` in your project and paste the base template below into it. By default, all your custom styles here are not compiled because CSS classes are located in your specific project. Here it is needed to set up the Tailwind for your project and all required instructions are located in [Project Level Tailwind Stylesheet](#project-level-tailwind-stylesheet) chapter.
1137
1179
 
1138
1180
  ```html+django
1139
1181
  {% extends 'unfold/layouts/base_simple.html' %}
@@ -1237,25 +1279,53 @@ Below you can find a more complex example which is using multiple components and
1237
1279
 
1238
1280
  #### List of available components <!-- omit from toc -->
1239
1281
 
1240
- | Component | Description | Arguments |
1241
- | --------------------------------- | ------------------------------ | -------------------------------- |
1242
- | unfold/components/chart/bar.html | Bar chart implementation | class, data, height, width |
1243
- | unfold/components/chart/line.html | Line chart implementation | class, data, height, width |
1244
- | unfold/components/card.html | Card component | class, title, footer, label |
1245
- | unfold/components/container.html | Wrapper for settings max width | class |
1246
- | unfold/components/flex.html | Flex items | class, col |
1247
- | unfold/components/navigation.html | List of navigation links | class, items |
1248
- | unfold/components/progress.html | Percentual progress bar | class, value, title, description |
1249
- | unfold/components/separator.html | Separator, horizontal rule | class |
1250
- | unfold/components/text.html | Paragraph of text | class |
1251
- | unfold/components/title.html | Basic heading element | class |
1252
- | unfold/components/button.html | Basic button element | submit |
1282
+ | Component | Description | Arguments |
1283
+ | --------------------------------- | ------------------------------ | ------------------------------------ |
1284
+ | unfold/components/button.html | Basic button element | submit |
1285
+ | unfold/components/card.html | Card component | class, title, footer, label, icon |
1286
+ | unfold/components/chart/bar.html | Bar chart implementation | class, data, height, width |
1287
+ | unfold/components/chart/line.html | Line chart implementation | class, data, height, width |
1288
+ | unfold/components/container.html | Wrapper for settings max width | class |
1289
+ | unfold/components/flex.html | Flex items | class, col |
1290
+ | unfold/components/icon.html | Icon element | class |
1291
+ | unfold/components/navigation.html | List of navigation links | class, items |
1292
+ | unfold/components/progress.html | Percentual progress bar | class, value, title, description |
1293
+ | unfold/components/separator.html | Separator, horizontal rule | class |
1294
+ | unfold/components/table.html | Table | table, card_included, striped |
1295
+ | unfold/components/text.html | Paragraph of text | class |
1296
+ | unfold/components/title.html | Basic heading element | class |
1297
+
1298
+
1299
+ #### Table component example
1300
+
1301
+ ```python
1302
+ from typing import Dict
1303
+ from django.http import HttpRequest
1304
+
1305
+
1306
+ def dashboard_callback(request: HttpRequest) -> Dict:
1307
+ return {
1308
+ "table_data": {
1309
+ "headers": ["col 1", "col 2"],
1310
+ "rows": [
1311
+ ["a", "b"],
1312
+ ["c", "d"],
1313
+ ]
1314
+ }
1315
+ }
1316
+ ```
1317
+
1318
+ ```django-html
1319
+ {% component "unfold/components/card" with title="Card title" %}
1320
+ {% component "unfold/components/table.html" with table=table_data card_included=1 striped=1 %}{% encomponent %}
1321
+ {% endcomponent %}
1322
+ ```
1253
1323
 
1254
1324
  ## Unfold development
1255
1325
 
1256
1326
  ### Pre-commit
1257
1327
 
1258
- Before adding any source code, it is recommended to have pre-commit installed on your local computer to check for all potential issues when comitting the code.
1328
+ Before adding any source code, it is recommended to have pre-commit installed on your local computer to check for all potential issues when committing the code.
1259
1329
 
1260
1330
  ```bash
1261
1331
  pip install pre-commit
@@ -1275,7 +1345,7 @@ To add a new feature or fix the easiest approach is to use django-unfold in comb
1275
1345
 
1276
1346
  ### Compiling Tailwind
1277
1347
 
1278
- At the moment project contains package.json with all dependencies required to compile new CSS file. Tailwind configuration file is set to check all html, js and py files for Tailwind's classeses occurrences.
1348
+ At the moment project contains package.json with all dependencies required to compile new CSS file. Tailwind configuration file is set to check all html, js and py files for Tailwind's classes occurrences.
1279
1349
 
1280
1350
  ```bash
1281
1351
  npm install
@@ -1285,7 +1355,7 @@ npm run tailwind:watch # run after each change in code
1285
1355
  npm run tailwind:build # run once
1286
1356
  ```
1287
1357
 
1288
- 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**.
1358
+ Some components like datepickers, calendars or selectors in admin was not possible to style by overriding html templates so their default styles are overridden in **styles.css**.
1289
1359
 
1290
1360
  **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.
1291
1361
 
@@ -9,7 +9,7 @@
9
9
  ![Code Style - Ruff](https://img.shields.io/badge/code%20style-ruff-30173D.svg?style=for-the-badge)
10
10
  ![Pre Commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge)
11
11
 
12
- 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.
12
+ Unfold is a theme for Django admin incorporating most common practices for building full-fledged admin areas. It is designed to work on top of default administration provided by Django.
13
13
 
14
14
  - **Unfold:** demo site is available at [unfoldadmin.com](https://unfoldadmin.com?utm_medium=github&utm_source=unfold)
15
15
  - **Formula:** repository with demo implementation at [github.com/unfoldadmin/formula](https://github.com/unfoldadmin/formula)
@@ -21,7 +21,7 @@ Did you decide to start using Unfold but you don't have time to make the switch
21
21
 
22
22
  ## Features <!-- omit from toc -->
23
23
 
24
- - **Visual**: provides new user interface based on Tailwind CSS framework
24
+ - **Visual**: provides a new user interface based on Tailwind CSS framework
25
25
  - **Sidebar:** simplifies definition of custom sidebar navigation with icons
26
26
  - **Dark mode:** supports both light and dark mode versions
27
27
  - **Configuration:** most of the basic options can be changed in settings.py
@@ -31,14 +31,16 @@ Did you decide to start using Unfold but you don't have time to make the switch
31
31
  - **Array widget:** built-in widget for `django.contrib.postgres.fields.ArrayField`
32
32
  - **Filters:** custom dropdown, numeric, datetime, and text fields
33
33
  - **Dashboard:** custom components for rapid dashboard development
34
+ - **Inline tabs:** group inlines into tab navigation in the change form
34
35
  - **Model tabs:** define custom tab navigations for models
35
- - **Fieldset tabs:** merge several fielsets into tabs in change form
36
- - **Colors:** possibility to override default color scheme
37
- - **Changeform modes:** display fields in changeform in compressed mode
36
+ - **Fieldset tabs:** merge several fieldsets into tabs in the change form
37
+ - **Colors:** possibility to override the default color scheme
38
+ - **Changeform modes:** display fields in the change form in compressed mode
38
39
  - **Third party packages:** default support for multiple popular applications
39
40
  - **Environment label**: distinguish between environments by displaying a label
40
41
  - **Nonrelated inlines**: displays nonrelated model as inline in changeform
41
42
  - **Parallel admin**: support for default admin in parallel with Unfold. [Admin migration guide](https://unfoldadmin.com/blog/migrating-django-admin-unfold/?utm_medium=github&utm_source=unfold)
43
+ - **Favicons**: built-in support for configuring various site favicons
42
44
  - **VS Code**: project configuration and development container is included
43
45
 
44
46
  ## Table of contents <!-- omit from toc -->
@@ -76,6 +78,7 @@ Did you decide to start using Unfold but you don't have time to make the switch
76
78
  - [Overriding template](#overriding-template)
77
79
  - [Custom variables](#custom-variables)
78
80
  - [Unfold components](#unfold-components)
81
+ - [Table component example](#table-component-example)
79
82
  - [Unfold development](#unfold-development)
80
83
  - [Pre-commit](#pre-commit)
81
84
  - [Poetry configuration](#poetry-configuration)
@@ -87,7 +90,7 @@ Did you decide to start using Unfold but you don't have time to make the switch
87
90
 
88
91
  ## Installation
89
92
 
90
- The installation process is minimal. Everything what is needed after installation is to put new application at the beginning of **INSTALLED_APPS**. Default admin configuration in urls.py can stay as it is and there are no changes required.
93
+ The installation process is minimal. Everything that is needed after installation is to put new application at the beginning of **INSTALLED_APPS**. The default admin configuration in urls.py can stay as it is, and no changes are required.
91
94
 
92
95
  ```python
93
96
  # settings.py
@@ -146,17 +149,24 @@ class CustomAdminClass(ModelAdmin):
146
149
 
147
150
  from django.contrib import admin
148
151
  from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
152
+ from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
149
153
  from django.contrib.auth.models import User
150
154
 
151
155
  from unfold.admin import ModelAdmin
152
156
 
153
157
 
154
158
  admin.site.unregister(User)
159
+ admin.site.unregister(Group)
155
160
 
156
161
 
157
162
  @admin.register(User)
158
163
  class UserAdmin(BaseUserAdmin, ModelAdmin):
159
164
  pass
165
+
166
+
167
+ @admin.register(Group)
168
+ class GroupAdmin(BaseGroupAdmin, ModelAdmin):
169
+ pass
160
170
  ```
161
171
 
162
172
  ## Configuration
@@ -185,6 +195,14 @@ UNFOLD = {
185
195
  "dark": lambda request: static("logo-dark.svg"), # dark mode
186
196
  },
187
197
  "SITE_SYMBOL": "speed", # symbol from icon set
198
+ "SITE_FAVICONS": [
199
+ {
200
+ "rel": "icon",
201
+ "sizes": "32x32",
202
+ "type": "image/svg+xml",
203
+ "href": lambda request: static("favicon.svg"),
204
+ },
205
+ ],
188
206
  "SHOW_HISTORY": True, # show/hide "History" button, default: True
189
207
  "SHOW_VIEW_ON_SITE": True, # show/hide "View on site" button, default: True
190
208
  "ENVIRONMENT": "sample_app.environment_callback",
@@ -231,6 +249,7 @@ UNFOLD = {
231
249
  {
232
250
  "title": _("Navigation"),
233
251
  "separator": True, # Top border
252
+ "collapsible": True, # Collapsible group of links
234
253
  "items": [
235
254
  {
236
255
  "title": _("Dashboard"),
@@ -321,6 +340,9 @@ class CustomAdminClass(ModelAdmin):
321
340
  # Display submit button in filters
322
341
  list_filter_submit = False
323
342
 
343
+ # Display changelist in fullwidth
344
+ list_fullwidth = False
345
+
324
346
  # Position horizontal scrollbar in changelist at the top
325
347
  list_horizontal_scrollbar_top = False
326
348
 
@@ -417,7 +439,7 @@ class UserAdmin(ModelAdmin):
417
439
  actions_detail = ["change_detail_action_block"]
418
440
  actions_submit_line = ["submit_line_action_activate"]
419
441
 
420
- @action(description=_("Save & Activate"))
442
+ @action(description=_("Save & Activate"), permissions=["submit_line_action_activate"])
421
443
  def submit_line_action_activate(self, request: HttpRequest, obj: User):
422
444
  """
423
445
  If instance is modified in any way, it also needs to be saved,
@@ -429,6 +451,9 @@ class UserAdmin(ModelAdmin):
429
451
  obj.is_active = True
430
452
  obj.save()
431
453
 
454
+ def has_submit_line_action_activate_permission(self, request: HttpRequest, object_id: Union[str, int]):
455
+ pass
456
+
432
457
  @action(description=_("Import"), url_path="import")
433
458
  def changelist_global_action_import(self, request: HttpRequest):
434
459
  """
@@ -453,7 +478,7 @@ class UserAdmin(ModelAdmin):
453
478
  """
454
479
  return redirect(f"https://example.com/{object_id}")
455
480
 
456
- @action(description=_("Detail"), url_path="detail-action", attrs={"target": "_blank"})
481
+ @action(description=_("Detail"), url_path="detail-action", attrs={"target": "_blank"}, permissions=["change_detail_action_block"])
457
482
  def change_detail_action_block(self, request: HttpRequest, object_id: int):
458
483
  """
459
484
  Handler for detail action.
@@ -468,6 +493,10 @@ class UserAdmin(ModelAdmin):
468
493
  return redirect(
469
494
  reverse_lazy("admin:users_user_change", args=(object_id,))
470
495
  )
496
+
497
+
498
+ def has_change_detail_action_block_permission(self, request: HttpRequest, object_id: Union[str, int]):
499
+ pass
471
500
  ```
472
501
 
473
502
  ### Action with form example
@@ -539,7 +568,7 @@ Text input field which allows filtering by the free string submitted by the user
539
568
 
540
569
  `FieldTextFilter` requires just a model field name and the filter will make `__icontains` search on this field. There are no other things to configure so the integration in `list_filter` will be just one new row looking like `("model_field_name", FieldTextFilter)`.
541
570
 
542
- In the case of the `TextFilter`, it is needed the write a whole new class inheriting from `TextFilter` with a custom implementation of the `queryset` method and the `parameter_name` attribute. This attribute will be a representation of the search query parameter name in URI. The benefit of the `TextFilter` is the possibility of writing complex queries.
571
+ In the case of the `TextFilter`, it is needed to write a whole new class inheriting from `TextFilter` with a custom implementation of the `queryset` method and the `parameter_name` attribute. This attribute will be a representation of the search query parameter name in URI. The benefit of the `TextFilter` is the possibility of writing complex queries.
543
572
 
544
573
  ```python
545
574
  from django.contrib import admin
@@ -574,7 +603,7 @@ class MyAdmin(ModelAdmin):
574
603
 
575
604
  Dropdown filters will display a select field with a list of options. Unfold contains two types of dropdowns: `ChoicesDropdownFilter` and `RelatedDropdownFilter`.
576
605
 
577
- The difference between them is that `ChoicesDropdownFilter` will collect a list of options based on the `choices` attribute of the model field so most commonly it will be used in combination with `CharField` with specified `choices`. On the other side, `RelatedDropdownFilter` needs a one-to-many or many-to-many foreign key to display options.
606
+ The difference between them is that `ChoicesDropdownFilter` will collect a list of options based on the `choices` attribute of the model field so most commonly it will be used in combination with `CharField` with specified `choices`. On the other hand, `RelatedDropdownFilter` needs a one-to-many or many-to-many foreign key to display options.
578
607
 
579
608
  **Note:** At the moment Unfold does not implement a dropdown with an autocomplete functionality, so it is important not to use dropdowns displaying large datasets.
580
609
 
@@ -883,6 +912,19 @@ class MyModelAdmin(ModelAdmin):
883
912
  )
884
913
  ```
885
914
 
915
+ Inlines can be grouped into tab navigation by specifying `tab` attribute in the inline class.
916
+
917
+ ```python
918
+ # admin.py
919
+
920
+ from unfold.admin import TabularInline
921
+
922
+
923
+ class MyInline(TabularInline):
924
+ model = User
925
+ tab = True
926
+ ```
927
+
886
928
  ## Third party packages
887
929
 
888
930
  ### django-celery-beat
@@ -952,11 +994,11 @@ class ClockedScheduleAdmin(BaseClockedScheduleAdmin, ModelAdmin):
952
994
 
953
995
  ### django-guardian
954
996
 
955
- 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.
997
+ Adding support for django-guardian is quite straightforward in Unfold, just add `unfold.contrib.guardian` to `INSTALLED_APPS` at the beginning 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.
956
998
 
957
999
  ### django-import-export
958
1000
 
959
- 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.
1001
+ 1. Add `unfold.contrib.import_export` to `INSTALLED_APPS` at the beginning of the file. This action will override all templates coming from the application.
960
1002
  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.
961
1003
 
962
1004
  ```python
@@ -1028,7 +1070,7 @@ This application is supported in Unfold by default. It is not needed to add any
1028
1070
 
1029
1071
  ### django-simple-history
1030
1072
 
1031
- 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.
1073
+ 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 overridden by Unfold.
1032
1074
 
1033
1075
  ## User Admin Form
1034
1076
 
@@ -1109,7 +1151,7 @@ npx tailwindcss -o your_project/static/css/styles.css --watch --minify
1109
1151
 
1110
1152
  ### Overriding template
1111
1153
 
1112
- Create `templates/admin/index.html` in your project and paste the base template below into it. By default, all your custom styles here are not compiled because CSS classes are located in your specific project. Here it is needed to set up the Tailwind for your project and all requried instructions are located in [Project Level Tailwind Stylesheet](#project-level-tailwind-stylesheet) chapter.
1154
+ Create `templates/admin/index.html` in your project and paste the base template below into it. By default, all your custom styles here are not compiled because CSS classes are located in your specific project. Here it is needed to set up the Tailwind for your project and all required instructions are located in [Project Level Tailwind Stylesheet](#project-level-tailwind-stylesheet) chapter.
1113
1155
 
1114
1156
  ```html+django
1115
1157
  {% extends 'unfold/layouts/base_simple.html' %}
@@ -1213,25 +1255,53 @@ Below you can find a more complex example which is using multiple components and
1213
1255
 
1214
1256
  #### List of available components <!-- omit from toc -->
1215
1257
 
1216
- | Component | Description | Arguments |
1217
- | --------------------------------- | ------------------------------ | -------------------------------- |
1218
- | unfold/components/chart/bar.html | Bar chart implementation | class, data, height, width |
1219
- | unfold/components/chart/line.html | Line chart implementation | class, data, height, width |
1220
- | unfold/components/card.html | Card component | class, title, footer, label |
1221
- | unfold/components/container.html | Wrapper for settings max width | class |
1222
- | unfold/components/flex.html | Flex items | class, col |
1223
- | unfold/components/navigation.html | List of navigation links | class, items |
1224
- | unfold/components/progress.html | Percentual progress bar | class, value, title, description |
1225
- | unfold/components/separator.html | Separator, horizontal rule | class |
1226
- | unfold/components/text.html | Paragraph of text | class |
1227
- | unfold/components/title.html | Basic heading element | class |
1228
- | unfold/components/button.html | Basic button element | submit |
1258
+ | Component | Description | Arguments |
1259
+ | --------------------------------- | ------------------------------ | ------------------------------------ |
1260
+ | unfold/components/button.html | Basic button element | submit |
1261
+ | unfold/components/card.html | Card component | class, title, footer, label, icon |
1262
+ | unfold/components/chart/bar.html | Bar chart implementation | class, data, height, width |
1263
+ | unfold/components/chart/line.html | Line chart implementation | class, data, height, width |
1264
+ | unfold/components/container.html | Wrapper for settings max width | class |
1265
+ | unfold/components/flex.html | Flex items | class, col |
1266
+ | unfold/components/icon.html | Icon element | class |
1267
+ | unfold/components/navigation.html | List of navigation links | class, items |
1268
+ | unfold/components/progress.html | Percentual progress bar | class, value, title, description |
1269
+ | unfold/components/separator.html | Separator, horizontal rule | class |
1270
+ | unfold/components/table.html | Table | table, card_included, striped |
1271
+ | unfold/components/text.html | Paragraph of text | class |
1272
+ | unfold/components/title.html | Basic heading element | class |
1273
+
1274
+
1275
+ #### Table component example
1276
+
1277
+ ```python
1278
+ from typing import Dict
1279
+ from django.http import HttpRequest
1280
+
1281
+
1282
+ def dashboard_callback(request: HttpRequest) -> Dict:
1283
+ return {
1284
+ "table_data": {
1285
+ "headers": ["col 1", "col 2"],
1286
+ "rows": [
1287
+ ["a", "b"],
1288
+ ["c", "d"],
1289
+ ]
1290
+ }
1291
+ }
1292
+ ```
1293
+
1294
+ ```django-html
1295
+ {% component "unfold/components/card" with title="Card title" %}
1296
+ {% component "unfold/components/table.html" with table=table_data card_included=1 striped=1 %}{% encomponent %}
1297
+ {% endcomponent %}
1298
+ ```
1229
1299
 
1230
1300
  ## Unfold development
1231
1301
 
1232
1302
  ### Pre-commit
1233
1303
 
1234
- Before adding any source code, it is recommended to have pre-commit installed on your local computer to check for all potential issues when comitting the code.
1304
+ Before adding any source code, it is recommended to have pre-commit installed on your local computer to check for all potential issues when committing the code.
1235
1305
 
1236
1306
  ```bash
1237
1307
  pip install pre-commit
@@ -1251,7 +1321,7 @@ To add a new feature or fix the easiest approach is to use django-unfold in comb
1251
1321
 
1252
1322
  ### Compiling Tailwind
1253
1323
 
1254
- At the moment project contains package.json with all dependencies required to compile new CSS file. Tailwind configuration file is set to check all html, js and py files for Tailwind's classeses occurrences.
1324
+ At the moment project contains package.json with all dependencies required to compile new CSS file. Tailwind configuration file is set to check all html, js and py files for Tailwind's classes occurrences.
1255
1325
 
1256
1326
  ```bash
1257
1327
  npm install
@@ -1261,7 +1331,7 @@ npm run tailwind:watch # run after each change in code
1261
1331
  npm run tailwind:build # run once
1262
1332
  ```
1263
1333
 
1264
- 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**.
1334
+ Some components like datepickers, calendars or selectors in admin was not possible to style by overriding html templates so their default styles are overridden in **styles.css**.
1265
1335
 
1266
1336
  **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.
1267
1337
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-unfold"
3
- version = "0.30.0"
3
+ version = "0.32.0"
4
4
  description = "Modern Django admin theme for seamless interface development"
5
5
  license = "MIT"
6
6
  readme = "README.md"