django-unfold 0.67.0__tar.gz → 0.68.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. {django_unfold-0.67.0 → django_unfold-0.68.0}/PKG-INFO +8 -5
  2. {django_unfold-0.67.0 → django_unfold-0.68.0}/README.md +6 -2
  3. {django_unfold-0.67.0 → django_unfold-0.68.0}/pyproject.toml +13 -15
  4. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/admin.py +73 -13
  5. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/components.py +2 -2
  6. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/admin/choice_filters.py +13 -1
  7. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/admin/mixins.py +3 -3
  8. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/admin/numeric_filters.py +6 -6
  9. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/widgets.py +5 -5
  10. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/inlines/admin.py +3 -3
  11. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/inlines/forms.py +5 -4
  12. django_unfold-0.68.0/src/unfold/dataclasses.py +42 -0
  13. django_unfold-0.68.0/src/unfold/datasets.py +69 -0
  14. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/decorators.py +19 -19
  15. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/fields.py +3 -5
  16. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/forms.py +19 -7
  17. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/mixins/action_model_admin.py +11 -10
  18. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/mixins/base_model_admin.py +6 -6
  19. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/sites.py +14 -17
  20. django_unfold-0.68.0/src/unfold/static/unfold/css/styles.css +2 -0
  21. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/app.js +3 -1
  22. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/styles.css +21 -16
  23. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/change_form.html +5 -1
  24. django_unfold-0.68.0/src/unfold/templates/admin/change_list_results.html +68 -0
  25. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/edit_inline/stacked.html +1 -1
  26. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/search_form.html +5 -3
  27. django_unfold-0.68.0/src/unfold/templates/unfold/helpers/change_list_headers.html +65 -0
  28. django_unfold-0.68.0/src/unfold/templates/unfold/helpers/dataset.html +19 -0
  29. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_field.html +1 -1
  30. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/empty_results.html +6 -4
  31. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/field_readonly_value_file.html +1 -1
  32. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/tab_items.html +6 -0
  33. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templatetags/unfold.py +18 -13
  34. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templatetags/unfold_list.py +64 -8
  35. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/typing.py +5 -6
  36. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/utils.py +9 -9
  37. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/views.py +15 -1
  38. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/widgets.py +30 -29
  39. django_unfold-0.67.0/src/unfold/dataclasses.py +0 -42
  40. django_unfold-0.67.0/src/unfold/static/unfold/css/styles.css +0 -2
  41. django_unfold-0.67.0/src/unfold/templates/admin/change_list_results.html +0 -120
  42. {django_unfold-0.67.0 → django_unfold-0.68.0}/LICENSE.md +0 -0
  43. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/__init__.py +0 -0
  44. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/apps.py +0 -0
  45. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/checks.py +0 -0
  46. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/__init__.py +0 -0
  47. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/constance/__init__.py +0 -0
  48. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/constance/apps.py +0 -0
  49. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/constance/settings.py +0 -0
  50. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/constance/templates/admin/constance/change_list.html +0 -0
  51. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/constance/templates/admin/constance/includes/results_list.html +0 -0
  52. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/__init__.py +0 -0
  53. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/admin/__init__.py +0 -0
  54. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/admin/autocomplete_filters.py +0 -0
  55. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/admin/datetime_filters.py +0 -0
  56. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/admin/dropdown_filters.py +0 -0
  57. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/admin/text_filters.py +0 -0
  58. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/apps.py +0 -0
  59. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/forms.py +0 -0
  60. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/static/unfold/filters/css/nouislider/LICENSE +0 -0
  61. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/static/unfold/filters/css/nouislider/nouislider.min.css +0 -0
  62. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/static/unfold/filters/js/DateTimeShortcuts.js +0 -0
  63. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/static/unfold/filters/js/admin-numeric-filter.js +0 -0
  64. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/static/unfold/filters/js/nouislider/LICENSE +0 -0
  65. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/static/unfold/filters/js/nouislider/nouislider.min.js +0 -0
  66. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/static/unfold/filters/js/wnumb/LICENSE +0 -0
  67. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/static/unfold/filters/js/wnumb/wNumb.min.js +0 -0
  68. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_date_range.html +0 -0
  69. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_datetime_range.html +0 -0
  70. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_field.html +0 -0
  71. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_range.html +0 -0
  72. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_single.html +0 -0
  73. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html +0 -0
  74. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/__init__.py +0 -0
  75. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/apps.py +0 -0
  76. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/static/unfold/forms/css/trix/LICENSE +0 -0
  77. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/static/unfold/forms/css/trix/trix.css +0 -0
  78. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix/LICENSE +0 -0
  79. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix/trix.js +0 -0
  80. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix.config.js +0 -0
  81. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/templates/unfold/forms/array.html +0 -0
  82. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/templates/unfold/forms/helpers/toolbar.html +0 -0
  83. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/forms/templates/unfold/forms/wysiwyg.html +0 -0
  84. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/guardian/__init__.py +0 -0
  85. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/guardian/apps.py +0 -0
  86. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/change_form.html +0 -0
  87. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/field.html +0 -0
  88. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage.html +0 -0
  89. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_group.html +0 -0
  90. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_user.html +0 -0
  91. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/guardian/templates/unfold/guardian/group_form.html +0 -0
  92. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/guardian/templates/unfold/guardian/user_form.html +0 -0
  93. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/__init__.py +0 -0
  94. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/apps.py +0 -0
  95. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/forms.py +0 -0
  96. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/base.html +0 -0
  97. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_form.html +0 -0
  98. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_export.html +0 -0
  99. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_export_item.html +0 -0
  100. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import.html +0 -0
  101. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import_export.html +0 -0
  102. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import_item.html +0 -0
  103. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/export.html +0 -0
  104. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/import.html +0 -0
  105. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_confirm.html +0 -0
  106. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_errors.html +0 -0
  107. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_form.html +0 -0
  108. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_preview.html +0 -0
  109. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_validation.html +0 -0
  110. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/import_export/templates/admin/import_export/resource_fields_list.html +0 -0
  111. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/inlines/__init__.py +0 -0
  112. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/inlines/apps.py +0 -0
  113. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/inlines/checks.py +0 -0
  114. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/location_field/__init__.py +0 -0
  115. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/location_field/apps.py +0 -0
  116. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/location_field/templates/location_field/map_widget.html +0 -0
  117. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/simple_history/__init__.py +0 -0
  118. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/simple_history/apps.py +0 -0
  119. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/simple_history/templates/simple_history/object_history.html +0 -0
  120. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/simple_history/templates/simple_history/object_history_form.html +0 -0
  121. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/simple_history/templates/simple_history/object_history_list.html +0 -0
  122. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/contrib/simple_history/templates/simple_history/submit_line.html +0 -0
  123. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/enums.py +0 -0
  124. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/exceptions.py +0 -0
  125. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/layout.py +0 -0
  126. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/mixins/__init__.py +0 -0
  127. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/overrides.py +0 -0
  128. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/paginator.py +0 -0
  129. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/sections.py +0 -0
  130. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/settings.py +0 -0
  131. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/admin/js/admin/RelatedObjectLookups.js +0 -0
  132. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/admin/js/inlines.js +0 -0
  133. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/css/simplebar/LICENSE +0 -0
  134. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/css/simplebar/simplebar.css +0 -0
  135. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/fonts/inter/Inter-Bold.woff2 +0 -0
  136. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/fonts/inter/Inter-Medium.woff2 +0 -0
  137. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/fonts/inter/Inter-Regular.woff2 +0 -0
  138. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/fonts/inter/Inter-SemiBold.woff2 +0 -0
  139. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/fonts/inter/LICENSE +0 -0
  140. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/fonts/inter/styles.css +0 -0
  141. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/fonts/material-symbols/LICENSE +0 -0
  142. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/fonts/material-symbols/Material-Symbols-Outlined.woff2 +0 -0
  143. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/fonts/material-symbols/styles.css +0 -0
  144. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/alpine/LICENSE +0 -0
  145. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/alpine/alpine.anchor.js +0 -0
  146. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/alpine/alpine.js +0 -0
  147. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/alpine/alpine.persist.js +0 -0
  148. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/alpine/alpine.resize.js +0 -0
  149. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/alpine/alpine.sort.js +0 -0
  150. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/chart/LICENSE +0 -0
  151. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/chart/chart.js +0 -0
  152. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/htmx/LICENSE +0 -0
  153. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/htmx/htmx.js +0 -0
  154. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/select2.init.js +0 -0
  155. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/simplebar/LICENSE +0 -0
  156. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/static/unfold/js/simplebar/simplebar.js +0 -0
  157. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/actions.html +0 -0
  158. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/app_index.html +0 -0
  159. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/app_list.html +0 -0
  160. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/auth/user/add_form.html +0 -0
  161. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/auth/user/change_password.html +0 -0
  162. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/base.html +0 -0
  163. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/base_site.html +0 -0
  164. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/change_form_object_tools.html +0 -0
  165. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/change_list.html +0 -0
  166. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/change_list_object_tools.html +0 -0
  167. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/date_hierarchy.html +0 -0
  168. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/delete_confirmation.html +0 -0
  169. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/delete_selected_confirmation.html +0 -0
  170. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/edit_inline/tabular.html +0 -0
  171. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/filter.html +0 -0
  172. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/includes/fieldset.html +0 -0
  173. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/includes/object_delete_summary.html +0 -0
  174. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/index.html +0 -0
  175. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/login.html +0 -0
  176. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/nav_sidebar.html +0 -0
  177. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/object_history.html +0 -0
  178. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/pagination.html +0 -0
  179. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/admin/submit_line.html +0 -0
  180. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/auth/widgets/read_only_password_hash.html +0 -0
  181. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/registration/logged_out.html +0 -0
  182. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/registration/password_change_done.html +0 -0
  183. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/registration/password_change_form.html +0 -0
  184. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/button.html +0 -0
  185. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/card.html +0 -0
  186. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/chart/bar.html +0 -0
  187. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/chart/cohort.html +0 -0
  188. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/chart/line.html +0 -0
  189. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/container.html +0 -0
  190. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/flex.html +0 -0
  191. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/icon.html +0 -0
  192. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/layer.html +0 -0
  193. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/navigation.html +0 -0
  194. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/progress.html +0 -0
  195. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/separator.html +0 -0
  196. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/table.html +0 -0
  197. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/text.html +0 -0
  198. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/title.html +0 -0
  199. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/components/tracker.html +0 -0
  200. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/account_links.html +0 -0
  201. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/actions_row.html +0 -0
  202. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/add_link.html +0 -0
  203. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/app_list.html +0 -0
  204. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/app_list_default.html +0 -0
  205. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/attrs.html +0 -0
  206. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/boolean.html +0 -0
  207. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/breadcrumb_item.html +0 -0
  208. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/change_list_actions.html +0 -0
  209. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/change_list_filter.html +0 -0
  210. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/change_list_filter_actions.html +0 -0
  211. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/command.html +0 -0
  212. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/command_history.html +0 -0
  213. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/command_results.html +0 -0
  214. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/delete_submit_line.html +0 -0
  215. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/display_dropdown.html +0 -0
  216. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/display_header.html +0 -0
  217. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/display_label.html +0 -0
  218. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_delete.html +0 -0
  219. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_error.html +0 -0
  220. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_heading.html +0 -0
  221. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_row.html +0 -0
  222. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_title.html +0 -0
  223. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/field.html +0 -0
  224. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/field_readonly.html +0 -0
  225. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/field_readonly_value.html +0 -0
  226. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/fieldset_row.html +0 -0
  227. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/fieldset_row_checkbox.html +0 -0
  228. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/fieldset_row_field.html +0 -0
  229. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/fieldsets_tabs.html +0 -0
  230. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/form_errors.html +0 -0
  231. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/form_label.html +0 -0
  232. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/header.html +0 -0
  233. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/header_back_button.html +0 -0
  234. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/header_title.html +0 -0
  235. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/help_text.html +0 -0
  236. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/history.html +0 -0
  237. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/label.html +0 -0
  238. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/language_form.html +0 -0
  239. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/language_switch.html +0 -0
  240. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/messages/debug.html +0 -0
  241. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/messages/error.html +0 -0
  242. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/messages/errornote.html +0 -0
  243. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/messages/info.html +0 -0
  244. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/messages/success.html +0 -0
  245. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/messages/warning.html +0 -0
  246. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/messages.html +0 -0
  247. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/navigation.html +0 -0
  248. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/navigation_header.html +0 -0
  249. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/pagination.html +0 -0
  250. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/pagination_current_item.html +0 -0
  251. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/pagination_default.html +0 -0
  252. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/pagination_ellipsis.html +0 -0
  253. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/pagination_infinite.html +0 -0
  254. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/pagination_inline.html +0 -0
  255. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/popup_header.html +0 -0
  256. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/search.html +0 -0
  257. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/search_results.html +0 -0
  258. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/shortcut.html +0 -0
  259. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/site_branding.html +0 -0
  260. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/site_dropdown.html +0 -0
  261. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/site_icon.html +0 -0
  262. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/site_logo.html +0 -0
  263. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/submit.html +0 -0
  264. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/tab_action.html +0 -0
  265. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/tab_actions.html +0 -0
  266. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/tab_list.html +0 -0
  267. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/theme_switch.html +0 -0
  268. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/unauthenticated_header.html +0 -0
  269. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/unauthenticated_title.html +0 -0
  270. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/userlinks.html +0 -0
  271. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/helpers/welcomemsg.html +0 -0
  272. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/layouts/base.html +0 -0
  273. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/layouts/base_simple.html +0 -0
  274. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/layouts/skeleton.html +0 -0
  275. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/layouts/unauthenticated.html +0 -0
  276. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/templatetags/preserve_changelist_filters.html +0 -0
  277. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/clearable_file_input.html +0 -0
  278. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/clearable_file_input_small.html +0 -0
  279. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/date.html +0 -0
  280. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/foreign_key_raw_id.html +0 -0
  281. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/radio.html +0 -0
  282. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/radio_option.html +0 -0
  283. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/range.html +0 -0
  284. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/related_widget_wrapper.html +0 -0
  285. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/select.html +0 -0
  286. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/split_datetime.html +0 -0
  287. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/split_datetime_vertical.html +0 -0
  288. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/split_money.html +0 -0
  289. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/text.html +0 -0
  290. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/textarea.html +0 -0
  291. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/time.html +0 -0
  292. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold/widgets/url.html +0 -0
  293. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/display_form.html +0 -0
  294. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/errors.html +0 -0
  295. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/errors_formset.html +0 -0
  296. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/field.html +0 -0
  297. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/inputs.html +0 -0
  298. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/attrs.html +0 -0
  299. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/baseinput.html +0 -0
  300. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/button.html +0 -0
  301. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/buttonholder.html +0 -0
  302. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/checkbox.html +0 -0
  303. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/column.html +0 -0
  304. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/div.html +0 -0
  305. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/field_errors.html +0 -0
  306. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/fieldset.html +0 -0
  307. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/fieldset_subheader.html +0 -0
  308. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/help_text.html +0 -0
  309. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/help_text_and_errors.html +0 -0
  310. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/hr.html +0 -0
  311. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/radio_checkbox_select.html +0 -0
  312. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/row.html +0 -0
  313. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/layout/table_inline_formset.html +0 -0
  314. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/uni_form.html +0 -0
  315. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/whole_uni_form.html +0 -0
  316. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templates/unfold_crispy/whole_uni_formset.html +0 -0
  317. {django_unfold-0.67.0 → django_unfold-0.68.0}/src/unfold/templatetags/__init__.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-unfold
3
- Version: 0.67.0
3
+ Version: 0.68.0
4
4
  Summary: Modern Django admin theme for seamless interface development
5
5
  License: MIT
6
6
  License-File: LICENSE.md
7
7
  Keywords: django,admin,tailwind,theme
8
- Requires-Python: >=3.9
8
+ Requires-Python: >=3.10,<4.0
9
9
  Classifier: Environment :: Web Environment
10
10
  Classifier: Framework :: Django
11
11
  Classifier: Intended Audience :: Developers
@@ -13,7 +13,6 @@ Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python
15
15
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.9
17
16
  Classifier: Programming Language :: Python :: 3.10
18
17
  Classifier: Programming Language :: Python :: 3.11
19
18
  Classifier: Programming Language :: Python :: 3.12
@@ -24,7 +23,7 @@ Project-URL: Homepage, https://unfoldadmin.com
24
23
  Project-URL: Repository, https://github.com/unfoldadmin/django-unfold
25
24
  Description-Content-Type: text/markdown
26
25
 
27
- ![screenshot](https://github.com/user-attachments/assets/87aaad04-f454-42aa-b9ac-e14d41f189ac)
26
+ [![screenshot](https://github.com/user-attachments/assets/8c2dc5c1-480b-49ad-bd2e-57369ca4e306)](https://unfoldadmin.com)
28
27
 
29
28
  ## Unfold - Django Admin Theme
30
29
 
@@ -59,13 +58,16 @@ If you need assistance with integrating or customizing Unfold, support packages
59
58
 
60
59
  Unfold Studio lets you visually customize your Django admin without writing code — update colors, logos, sidebar, and interface styles to match your brand in minutes. Give your admin a polished, professional look that feels truly yours. Available at [unfoldadmin.com/studio](https://unfoldadmin.com/studio).
61
60
 
61
+ [![dashboards](https://github.com/user-attachments/assets/7c3124ab-2f59-4254-9222-8a57970f51a6)](https://unfoldadmin.com/studio)
62
+
63
+
62
64
  ## Fresh Features & Enhancements
63
65
 
66
+ - **Command**: Offers a command palette for quick searching across all models or custom-injected data
64
67
  - **django-constance**: Official support with a completely new design and UX improvements
65
68
  - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
66
69
  - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form
67
70
  - **Infinite paginator:** Efficiently handle large datasets with seamless pagination that reduces server load
68
- - **Checkbox & radio filters:** Enhanced filter options with checkbox and radio interfaces for intuitive filtering
69
71
 
70
72
  ## Core Features & Capabilities
71
73
 
@@ -84,6 +86,7 @@ Unfold Studio lets you visually customize your Django admin without writing code
84
86
  - **Model tabs:** Allow defining custom tab navigation for models
85
87
  - **Fieldset tabs:** Merge multiple fieldsets into tabs in the change form
86
88
  - **Sortable inlines:** Allow sorting inlines by dragging and dropping
89
+ - **Command**: Offers a command palette for quick searching across all models or custom-injected data
87
90
  - **Environment label:** Distinguish between environments by displaying a label
88
91
  - **Nonrelated inlines:** Display nonrelated models as inlines in the change form
89
92
  - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
@@ -1,4 +1,4 @@
1
- ![screenshot](https://github.com/user-attachments/assets/87aaad04-f454-42aa-b9ac-e14d41f189ac)
1
+ [![screenshot](https://github.com/user-attachments/assets/8c2dc5c1-480b-49ad-bd2e-57369ca4e306)](https://unfoldadmin.com)
2
2
 
3
3
  ## Unfold - Django Admin Theme
4
4
 
@@ -33,13 +33,16 @@ If you need assistance with integrating or customizing Unfold, support packages
33
33
 
34
34
  Unfold Studio lets you visually customize your Django admin without writing code — update colors, logos, sidebar, and interface styles to match your brand in minutes. Give your admin a polished, professional look that feels truly yours. Available at [unfoldadmin.com/studio](https://unfoldadmin.com/studio).
35
35
 
36
+ [![dashboards](https://github.com/user-attachments/assets/7c3124ab-2f59-4254-9222-8a57970f51a6)](https://unfoldadmin.com/studio)
37
+
38
+
36
39
  ## Fresh Features & Enhancements
37
40
 
41
+ - **Command**: Offers a command palette for quick searching across all models or custom-injected data
38
42
  - **django-constance**: Official support with a completely new design and UX improvements
39
43
  - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
40
44
  - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form
41
45
  - **Infinite paginator:** Efficiently handle large datasets with seamless pagination that reduces server load
42
- - **Checkbox & radio filters:** Enhanced filter options with checkbox and radio interfaces for intuitive filtering
43
46
 
44
47
  ## Core Features & Capabilities
45
48
 
@@ -58,6 +61,7 @@ Unfold Studio lets you visually customize your Django admin without writing code
58
61
  - **Model tabs:** Allow defining custom tab navigation for models
59
62
  - **Fieldset tabs:** Merge multiple fieldsets into tabs in the change form
60
63
  - **Sortable inlines:** Allow sorting inlines by dragging and dropping
64
+ - **Command**: Offers a command palette for quick searching across all models or custom-injected data
61
65
  - **Environment label:** Distinguish between environments by displaying a label
62
66
  - **Nonrelated inlines:** Display nonrelated models as inlines in the change form
63
67
  - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-unfold"
3
- version = "0.67.0"
3
+ version = "0.68.0"
4
4
  description = "Modern Django admin theme for seamless interface development"
5
5
  license = "MIT"
6
6
  readme = "README.md"
@@ -11,11 +11,11 @@ packages = [{ include = "unfold", from = "src" }]
11
11
  keywords = ["django", "admin", "tailwind", "theme"]
12
12
  classifiers = [
13
13
  "Programming Language :: Python",
14
- "Programming Language :: Python :: 3.9",
15
14
  "Programming Language :: Python :: 3.10",
16
15
  "Programming Language :: Python :: 3.11",
17
16
  "Programming Language :: Python :: 3.12",
18
17
  "Programming Language :: Python :: 3.13",
18
+ "Programming Language :: Python :: 3.14",
19
19
  "Operating System :: OS Independent",
20
20
  "Environment :: Web Environment",
21
21
  "Intended Audience :: Developers",
@@ -23,22 +23,23 @@ classifiers = [
23
23
  ]
24
24
 
25
25
  [tool.poetry.dependencies]
26
- python = ">=3.9"
26
+ python = ">=3.10,<4.0"
27
27
  django = ">=4.2"
28
28
 
29
29
  [tool.poetry.group.test.dependencies]
30
- pytest = "^8.3"
30
+ pytest = "^8.4"
31
31
  pytest-django = "^4.11"
32
- pytest-factoryboy = "^2.7.0"
33
- tox = "^4.26"
32
+ pytest-factoryboy = "^2.8"
33
+ tox = "^4.30"
34
34
  django-money = "^3.5"
35
35
 
36
36
  [tool.poetry.group.dev.dependencies]
37
- python-semantic-release = "^9.21"
37
+ python-semantic-release = "^10.4"
38
38
 
39
39
  [tool.ruff]
40
40
  fix = true
41
41
  line-length = 88
42
+ target-version = "py310"
42
43
 
43
44
  [tool.ruff.lint]
44
45
  select = [
@@ -59,20 +60,17 @@ ignore = [
59
60
  [tool.semantic_release]
60
61
  tag_format = "{version}"
61
62
  major_on_zero = false
63
+ allow_zero_version = true
62
64
  version_toml = ["pyproject.toml:tool.poetry.version"]
63
65
 
64
66
  [tool.semantic_release.changelog]
65
- template_dir = ".github/templates"
67
+ mode = "init"
66
68
  exclude_commit_patterns = [
67
69
  "chore: version bump",
68
- "chore(deps)",
69
- "chore(deps-dev)",
70
+ '''chore(?:\(deps\))?: .+''',
71
+ '''chore(?:\(deps-dev\))?: .+'''
70
72
  ]
71
73
 
72
- [tool.semantic_release.changelog.environment]
73
- trim_blocks = true
74
- lstrip_blocks = true
75
-
76
74
  [tool.semantic_release.publish]
77
75
  upload_to_vcs_release = false
78
76
 
@@ -90,7 +88,7 @@ legacy_tox_ini = """
90
88
  [tox]
91
89
  isolated_build = true
92
90
  envlist =
93
- python{39,310,311,312,313}-django{42,50,51,52}
91
+ python{310,311,312,313,314}-django{42,50,51,52}
94
92
 
95
93
  [testenv]
96
94
  skip_install = true
@@ -1,5 +1,5 @@
1
1
  from functools import update_wrapper
2
- from typing import Any, Optional
2
+ from typing import Any
3
3
 
4
4
  from django import forms
5
5
  from django.contrib.admin import ModelAdmin as BaseModelAdmin
@@ -7,6 +7,8 @@ from django.contrib.admin import StackedInline as BaseStackedInline
7
7
  from django.contrib.admin import TabularInline as BaseTabularInline
8
8
  from django.contrib.admin import display, helpers
9
9
  from django.contrib.admin.options import InlineModelAdmin
10
+ from django.contrib.admin.views import main
11
+ from django.contrib.admin.views.main import IGNORED_PARAMS
10
12
  from django.contrib.contenttypes.admin import (
11
13
  GenericStackedInline as BaseGenericStackedInline,
12
14
  )
@@ -23,6 +25,7 @@ from django.utils.translation import gettext_lazy as _
23
25
  from django.views import View
24
26
 
25
27
  from unfold.checks import UnfoldModelAdminChecks
28
+ from unfold.datasets import BaseDataset
26
29
  from unfold.forms import (
27
30
  ActionForm,
28
31
  PaginationGenericInlineFormSet,
@@ -47,6 +50,8 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
47
50
  action_form = ActionForm
48
51
  custom_urls = ()
49
52
  add_fieldsets = ()
53
+ ordering_field = None
54
+ hide_ordering_field = False
50
55
  list_horizontal_scrollbar_top = False
51
56
  list_filter_submit = False
52
57
  list_filter_sheet = True
@@ -58,6 +63,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
58
63
  change_form_after_template = None
59
64
  change_form_outer_before_template = None
60
65
  change_form_outer_after_template = None
66
+ change_form_datasets = ()
61
67
  compressed_fields = False
62
68
  readonly_preprocess_fields = {}
63
69
  warn_unsaved_form = False
@@ -72,7 +78,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
72
78
 
73
79
  for filter in self.get_list_filter(self.request):
74
80
  if (
75
- isinstance(filter, (tuple, list))
81
+ isinstance(filter, tuple | list)
76
82
  and hasattr(filter[1], "form_class")
77
83
  and hasattr(filter[1].form_class, "Media")
78
84
  ):
@@ -83,12 +89,61 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
83
89
  return media
84
90
 
85
91
  def changelist_view(
86
- self, request: HttpRequest, extra_context: Optional[dict[str, str]] = None
92
+ self, request: HttpRequest, extra_context: dict[str, str] | None = None
87
93
  ) -> TemplateResponse:
88
94
  self.request = request
95
+
96
+ if self.ordering_field and self.ordering_field not in self.list_editable:
97
+ list_editable = list(getattr(self, "list_editable", []))
98
+ list_editable.append(self.ordering_field)
99
+ self.list_editable = list_editable
100
+
89
101
  return super().changelist_view(request, extra_context)
90
102
 
91
- def get_fieldsets(self, request: HttpRequest, obj=None) -> FieldsetsType:
103
+ def changeform_view(
104
+ self,
105
+ request: HttpRequest,
106
+ object_id: str | None = None,
107
+ form_url: str = "",
108
+ extra_context: dict[str, Any] | None = None,
109
+ ) -> TemplateResponse:
110
+ self.request = request
111
+ extra_context = extra_context or {}
112
+ datasets = self.get_changeform_datasets(request)
113
+
114
+ # Monkeypatch IGNORED_PARAMS to add dataset page and search arguments into ignored params
115
+ ignored_params = []
116
+ for dataset in datasets:
117
+ ignored_params.append(f"{dataset.model._meta.model_name}-q")
118
+ ignored_params.append(f"{dataset.model._meta.model_name}-p")
119
+
120
+ main.IGNORED_PARAMS = (*IGNORED_PARAMS, *ignored_params)
121
+
122
+ rendered_datasets = []
123
+ for dataset in datasets:
124
+ rendered_datasets.append(
125
+ dataset(
126
+ request=request,
127
+ extra_context={
128
+ "object": object_id,
129
+ },
130
+ )
131
+ )
132
+
133
+ extra_context["datasets"] = rendered_datasets
134
+ return super().changeform_view(request, object_id, form_url, extra_context)
135
+
136
+ def get_list_display(self, request: HttpRequest) -> list[str]:
137
+ list_display = super().get_list_display(request)
138
+
139
+ if self.ordering_field and self.ordering_field not in list_display:
140
+ list_display.append(self.ordering_field)
141
+
142
+ return list_display
143
+
144
+ def get_fieldsets(
145
+ self, request: HttpRequest, obj: Model | None = None
146
+ ) -> FieldsetsType:
92
147
  if not obj and self.add_fieldsets:
93
148
  return self.add_fieldsets
94
149
  return super().get_fieldsets(request, obj)
@@ -119,7 +174,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
119
174
 
120
175
  actions_list_urls = [
121
176
  path(
122
- action.path,
177
+ f"{action.path.removesuffix('/')}/",
123
178
  wrap(action.method),
124
179
  name=action.action_name,
125
180
  )
@@ -128,7 +183,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
128
183
 
129
184
  action_detail_urls = [
130
185
  path(
131
- f"<path:object_id>/{action.path}",
186
+ f"<path:object_id>/{action.path.removesuffix('/')}/",
132
187
  wrap(action.method),
133
188
  name=action.action_name,
134
189
  )
@@ -137,7 +192,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
137
192
 
138
193
  action_row_urls = [
139
194
  path(
140
- f"<path:object_id>/{action.path}",
195
+ f"<path:object_id>/{action.path.removesuffix('/')}/",
141
196
  wrap(action.method),
142
197
  name=action.action_name,
143
198
  )
@@ -152,7 +207,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
152
207
  + urls
153
208
  )
154
209
 
155
- def _path_from_custom_url(self, custom_url) -> URLPattern:
210
+ def _path_from_custom_url(self, custom_url: tuple[str, str, View]) -> URLPattern:
156
211
  return path(
157
212
  custom_url[0],
158
213
  self.admin_site.admin_view(custom_url[2]),
@@ -161,13 +216,15 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
161
216
  )
162
217
 
163
218
  def get_action_choices(
164
- self, request: HttpRequest, default_choices=BLANK_CHOICE_DASH
165
- ):
219
+ self,
220
+ request: HttpRequest,
221
+ default_choices: list[tuple[str, str]] = BLANK_CHOICE_DASH,
222
+ ) -> list[tuple[str, str]]:
166
223
  default_choices = [("", _("Select action"))]
167
224
  return super().get_action_choices(request, default_choices)
168
225
 
169
226
  @display(description=mark_safe(checkbox.render("action_toggle_all", 1)))
170
- def action_checkbox(self, obj: Model):
227
+ def action_checkbox(self, obj: Model) -> str:
171
228
  return checkbox.render(helpers.ACTION_CHECKBOX_NAME, str(obj.pk))
172
229
 
173
230
  def response_change(self, request: HttpRequest, obj: Model) -> HttpResponse:
@@ -177,14 +234,14 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
177
234
  return res
178
235
 
179
236
  def response_add(
180
- self, request: HttpRequest, obj: Model, post_url_continue: Optional[str] = None
237
+ self, request: HttpRequest, obj: Model, post_url_continue: str | None = None
181
238
  ) -> HttpResponse:
182
239
  res = super().response_add(request, obj, post_url_continue)
183
240
  if "next" in request.GET:
184
241
  return redirect(request.GET["next"])
185
242
  return res
186
243
 
187
- def get_changelist(self, request, **kwargs):
244
+ def get_changelist(self, request: HttpRequest, **kwargs: Any) -> ChangeList:
188
245
  return ChangeList
189
246
 
190
247
  def get_formset_kwargs(
@@ -198,6 +255,9 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
198
255
 
199
256
  return formset_kwargs
200
257
 
258
+ def get_changeform_datasets(self, request: HttpRequest) -> list[type[BaseDataset]]:
259
+ return self.change_form_datasets
260
+
201
261
 
202
262
  class BaseInlineMixin:
203
263
  formfield_overrides = FORMFIELD_OVERRIDES_INLINE
@@ -1,4 +1,4 @@
1
- from typing import Any, Optional
1
+ from typing import Any
2
2
 
3
3
  from django.http import HttpRequest
4
4
 
@@ -21,7 +21,7 @@ class ComponentRegistry:
21
21
  cls._registry[class_name] = component_cls
22
22
 
23
23
  @classmethod
24
- def get_class(cls, class_name: str) -> Optional[type]:
24
+ def get_class(cls, class_name: str) -> type | None:
25
25
  return cls._registry.get(class_name)
26
26
 
27
27
  @classmethod
@@ -4,10 +4,11 @@ from typing import Any
4
4
  from django.contrib import admin
5
5
  from django.contrib.admin.views.main import ChangeList
6
6
  from django.core.validators import EMPTY_VALUES
7
- from django.db.models import QuerySet
7
+ from django.db.models import Model, QuerySet
8
8
  from django.http import HttpRequest
9
9
  from django.utils.translation import gettext_lazy as _
10
10
 
11
+ from unfold.admin import ModelAdmin
11
12
  from unfold.contrib.filters.admin.mixins import (
12
13
  ChoicesMixin,
13
14
  MultiValueMixin,
@@ -56,6 +57,17 @@ class CheckboxFilter(RadioFilter):
56
57
  form_class = CheckboxForm
57
58
  all_option = None
58
59
 
60
+ # TODO: remove once django 4.x is not supported
61
+ def __init__(
62
+ self,
63
+ request: HttpRequest,
64
+ params: dict[str, Any],
65
+ model: type[Model],
66
+ model_admin: ModelAdmin,
67
+ ) -> None:
68
+ self.request = request
69
+ super().__init__(request, params, model, model_admin)
70
+
59
71
  def value(self) -> list[Any]:
60
72
  return self.request.GET.getlist(self.parameter_name)
61
73
 
@@ -1,5 +1,5 @@
1
1
  from collections.abc import Generator
2
- from typing import Any, Optional
2
+ from typing import Any
3
3
 
4
4
  from django.contrib.admin.views.main import ChangeList
5
5
  from django.core.validators import EMPTY_VALUES
@@ -18,7 +18,7 @@ from unfold.contrib.filters.forms import (
18
18
 
19
19
 
20
20
  class ValueMixin:
21
- def value(self) -> Optional[str]:
21
+ def value(self) -> str | None:
22
22
  return (
23
23
  self.lookup_val[0]
24
24
  if self.lookup_val not in EMPTY_VALUES
@@ -29,7 +29,7 @@ class ValueMixin:
29
29
 
30
30
 
31
31
  class MultiValueMixin:
32
- def value(self) -> Optional[list[str]]:
32
+ def value(self) -> list[str] | None:
33
33
  return (
34
34
  self.lookup_val
35
35
  if self.lookup_val not in EMPTY_VALUES
@@ -1,4 +1,4 @@
1
- from typing import Any, Optional
1
+ from typing import Any
2
2
 
3
3
  from django.contrib import admin
4
4
  from django.contrib.admin.options import ModelAdmin
@@ -35,7 +35,7 @@ class SingleNumericFilter(admin.FieldListFilter):
35
35
  ) -> None:
36
36
  super().__init__(field, request, params, model, model_admin, field_path)
37
37
 
38
- if not isinstance(field, (DecimalField, IntegerField, FloatField, AutoField)):
38
+ if not isinstance(field, DecimalField | IntegerField | FloatField | AutoField):
39
39
  raise TypeError(
40
40
  f"Class {type(self.field)} is not supported for {self.__class__.__name__}."
41
41
  )
@@ -54,7 +54,7 @@ class SingleNumericFilter(admin.FieldListFilter):
54
54
 
55
55
  def queryset(
56
56
  self, request: HttpRequest, queryset: QuerySet[Any]
57
- ) -> Optional[QuerySet]:
57
+ ) -> QuerySet | None:
58
58
  if self.value():
59
59
  try:
60
60
  return queryset.filter(**{self.parameter_name: self.value()})
@@ -64,7 +64,7 @@ class SingleNumericFilter(admin.FieldListFilter):
64
64
  def value(self) -> Any:
65
65
  return self.used_parameters.get(self.parameter_name, None)
66
66
 
67
- def expected_parameters(self) -> list[Optional[str]]:
67
+ def expected_parameters(self) -> list[str | None]:
68
68
  return [self.parameter_name]
69
69
 
70
70
  def choices(self, changelist: ChangeList) -> tuple[dict[str, Any], ...]:
@@ -111,7 +111,7 @@ class RangeNumericFilter(RangeNumericMixin, admin.FieldListFilter):
111
111
  field_path: str,
112
112
  ) -> None:
113
113
  super().__init__(field, request, params, model, model_admin, field_path)
114
- if not isinstance(field, (DecimalField, IntegerField, FloatField, AutoField)):
114
+ if not isinstance(field, DecimalField | IntegerField | FloatField | AutoField):
115
115
  raise TypeError(
116
116
  f"Class {type(self.field)} is not supported for {self.__class__.__name__}."
117
117
  )
@@ -156,7 +156,7 @@ class SliderNumericFilter(RangeNumericFilter):
156
156
  else:
157
157
  max_value = None
158
158
 
159
- if isinstance(self.field, (FloatField, DecimalField)):
159
+ if isinstance(self.field, FloatField | DecimalField):
160
160
  decimals = self.MAX_DECIMALS
161
161
  step = self.STEP if self.STEP else self._get_min_step(self.MAX_DECIMALS)
162
162
  else:
@@ -1,4 +1,4 @@
1
- from typing import Any, Optional, Union
1
+ from typing import Any
2
2
 
3
3
  from django.core.validators import EMPTY_VALUES
4
4
  from django.forms import MultiWidget, Widget
@@ -35,7 +35,7 @@ class ArrayWidget(MultiWidget):
35
35
 
36
36
  def __init__(
37
37
  self,
38
- widget_class: Optional[type[Widget]] = None,
38
+ widget_class: type[Widget] | None = None,
39
39
  *args: Any,
40
40
  **kwargs: Any,
41
41
  ) -> None:
@@ -81,7 +81,7 @@ class ArrayWidget(MultiWidget):
81
81
  ) -> list:
82
82
  return data.getlist(name) not in [[""], *EMPTY_VALUES]
83
83
 
84
- def decompress(self, value: Union[str, list]) -> list:
84
+ def decompress(self, value: str | list) -> list:
85
85
  if isinstance(value, list):
86
86
  return value
87
87
  elif isinstance(value, str):
@@ -89,7 +89,7 @@ class ArrayWidget(MultiWidget):
89
89
 
90
90
  return []
91
91
 
92
- def _resolve_widgets(self, value: Optional[Union[list, str]]) -> None:
92
+ def _resolve_widgets(self, value: list | str | None) -> None:
93
93
  if value is None:
94
94
  value = []
95
95
 
@@ -112,7 +112,7 @@ class WysiwygWidget(Widget):
112
112
  "unfold/forms/js/trix.config.js",
113
113
  )
114
114
 
115
- def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
115
+ def __init__(self, attrs: dict[str, Any] | None = None) -> None:
116
116
  super().__init__(attrs)
117
117
 
118
118
  self.attrs.update(
@@ -1,5 +1,5 @@
1
1
  from functools import partial
2
- from typing import Any, Optional
2
+ from typing import Any
3
3
 
4
4
  from django import forms
5
5
  from django.contrib.admin.utils import NestedObjects, flatten_fieldsets
@@ -28,7 +28,7 @@ class NonrelatedInlineMixin:
28
28
  formset = NonrelatedInlineModelFormSet
29
29
 
30
30
  def get_formset(
31
- self, request: HttpRequest, obj: Optional[Model] = None, **kwargs: Any
31
+ self, request: HttpRequest, obj: Model | None = None, **kwargs: Any
32
32
  ):
33
33
  defaults = self._get_formset_defaults(request, obj, **kwargs)
34
34
 
@@ -41,7 +41,7 @@ class NonrelatedInlineMixin:
41
41
  )
42
42
 
43
43
  def _get_formset_defaults(
44
- self, request: HttpRequest, obj: Optional[Model] = None, **kwargs: Any
44
+ self, request: HttpRequest, obj: Model | None = None, **kwargs: Any
45
45
  ):
46
46
  """Return a BaseInlineFormSet class for use in admin add/change views."""
47
47
  if "fields" in kwargs:
@@ -1,4 +1,5 @@
1
- from typing import Any, Callable, Optional
1
+ from collections.abc import Callable
2
+ from typing import Any
2
3
 
3
4
  from django.db.models import Model, QuerySet
4
5
  from django.forms import BaseModelFormSet, ModelForm, modelformset_factory
@@ -9,7 +10,7 @@ from unfold.forms import PaginationFormSetMixin
9
10
  class NonrelatedInlineModelFormSet(PaginationFormSetMixin, BaseModelFormSet):
10
11
  def __init__(
11
12
  self,
12
- instance: Optional[Model] = None,
13
+ instance: Model | None = None,
13
14
  save_as_new: bool = False,
14
15
  **kwargs: Any,
15
16
  ) -> None:
@@ -33,9 +34,9 @@ class NonrelatedInlineModelFormSet(PaginationFormSetMixin, BaseModelFormSet):
33
34
 
34
35
  def nonrelated_inline_formset_factory(
35
36
  model: Model,
36
- queryset: Optional[QuerySet] = None,
37
+ queryset: QuerySet | None = None,
37
38
  formset: BaseModelFormSet = NonrelatedInlineModelFormSet,
38
- save_new_instance: Optional[Callable] = None,
39
+ save_new_instance: Callable | None = None,
39
40
  **kwargs: Any,
40
41
  ) -> BaseModelFormSet:
41
42
  inline_formset = modelformset_factory(model, formset=formset, **kwargs)
@@ -0,0 +1,42 @@
1
+ from collections.abc import Callable
2
+ from dataclasses import dataclass
3
+
4
+ from unfold.enums import ActionVariant
5
+
6
+ from .typing import ActionFunction
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class UnfoldAction:
11
+ action_name: str
12
+ method: ActionFunction
13
+ description: str
14
+ path: str
15
+ attrs: dict | None = None
16
+ object_id: int | str | None = None
17
+ icon: str | None = None
18
+ variant: ActionVariant | None = ActionVariant.DEFAULT
19
+
20
+
21
+ @dataclass
22
+ class SearchResult:
23
+ title: str
24
+ description: str
25
+ link: str
26
+ icon: str | None
27
+
28
+
29
+ @dataclass
30
+ class Favicon:
31
+ href: str | Callable
32
+ rel: str | None = None
33
+ type: str | None = None
34
+ sizes: str | None = None
35
+
36
+
37
+ @dataclass
38
+ class DropdownItem:
39
+ title: str
40
+ link: str | Callable
41
+ icon: str | None = None
42
+ attrs: dict | None = None