django-unfold 0.67.0__tar.gz → 0.69.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 (325) hide show
  1. {django_unfold-0.67.0 → django_unfold-0.69.0}/PKG-INFO +33 -41
  2. {django_unfold-0.67.0 → django_unfold-0.69.0}/README.md +31 -38
  3. {django_unfold-0.67.0 → django_unfold-0.69.0}/pyproject.toml +13 -15
  4. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/admin.py +46 -15
  5. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/components.py +2 -2
  6. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/admin/choice_filters.py +13 -1
  7. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/admin/mixins.py +3 -3
  8. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/admin/numeric_filters.py +6 -6
  9. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/widgets.py +5 -5
  10. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/inlines/admin.py +3 -3
  11. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/inlines/forms.py +5 -4
  12. django_unfold-0.69.0/src/unfold/dataclasses.py +42 -0
  13. django_unfold-0.69.0/src/unfold/datasets.py +90 -0
  14. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/decorators.py +19 -19
  15. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/fields.py +3 -5
  16. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/forms.py +41 -22
  17. django_unfold-0.69.0/src/unfold/mixins/__init__.py +5 -0
  18. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/mixins/action_model_admin.py +11 -10
  19. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/mixins/base_model_admin.py +6 -6
  20. django_unfold-0.69.0/src/unfold/mixins/dataset_model_admin.py +62 -0
  21. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/settings.py +1 -0
  22. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/sites.py +19 -18
  23. django_unfold-0.69.0/src/unfold/static/admin/js/actions.js +246 -0
  24. django_unfold-0.69.0/src/unfold/static/unfold/css/styles.css +2 -0
  25. django_unfold-0.69.0/src/unfold/static/unfold/fonts/material-symbols/Material-Symbols-Outlined.woff2 +0 -0
  26. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/app.js +3 -1
  27. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/styles.css +21 -16
  28. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/actions.html +2 -2
  29. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/change_form.html +10 -2
  30. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/change_list.html +1 -1
  31. django_unfold-0.69.0/src/unfold/templates/admin/change_list_results.html +68 -0
  32. django_unfold-0.69.0/src/unfold/templates/admin/dataset_actions.html +50 -0
  33. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/edit_inline/stacked.html +2 -8
  34. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/edit_inline/tabular.html +1 -7
  35. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/includes/fieldset.html +1 -3
  36. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/search_form.html +6 -4
  37. django_unfold-0.69.0/src/unfold/templates/registration/password_change_done.html +11 -0
  38. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/registration/password_change_form.html +10 -6
  39. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/change_list_actions.html +1 -1
  40. django_unfold-0.69.0/src/unfold/templates/unfold/helpers/change_list_headers.html +65 -0
  41. django_unfold-0.69.0/src/unfold/templates/unfold/helpers/dataset.html +31 -0
  42. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_field.html +1 -1
  43. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/empty_results.html +6 -4
  44. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/field_readonly_value_file.html +1 -1
  45. django_unfold-0.69.0/src/unfold/templates/unfold/helpers/fieldsets_tabs.html +24 -0
  46. django_unfold-0.69.0/src/unfold/templates/unfold/helpers/inline_heading.html +11 -0
  47. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/tab_items.html +9 -1
  48. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templatetags/unfold.py +64 -82
  49. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templatetags/unfold_list.py +76 -8
  50. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/typing.py +5 -6
  51. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/utils.py +9 -9
  52. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/views.py +15 -1
  53. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/widgets.py +31 -31
  54. django_unfold-0.67.0/src/unfold/dataclasses.py +0 -42
  55. django_unfold-0.67.0/src/unfold/mixins/__init__.py +0 -4
  56. django_unfold-0.67.0/src/unfold/static/unfold/css/styles.css +0 -2
  57. django_unfold-0.67.0/src/unfold/static/unfold/fonts/material-symbols/Material-Symbols-Outlined.woff2 +0 -0
  58. django_unfold-0.67.0/src/unfold/templates/admin/change_list_results.html +0 -120
  59. django_unfold-0.67.0/src/unfold/templates/registration/password_change_done.html +0 -12
  60. django_unfold-0.67.0/src/unfold/templates/unfold/helpers/fieldsets_tabs.html +0 -26
  61. {django_unfold-0.67.0 → django_unfold-0.69.0}/LICENSE.md +0 -0
  62. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/__init__.py +0 -0
  63. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/apps.py +0 -0
  64. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/checks.py +0 -0
  65. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/__init__.py +0 -0
  66. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/constance/__init__.py +0 -0
  67. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/constance/apps.py +0 -0
  68. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/constance/settings.py +0 -0
  69. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/constance/templates/admin/constance/change_list.html +0 -0
  70. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/constance/templates/admin/constance/includes/results_list.html +0 -0
  71. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/__init__.py +0 -0
  72. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/admin/__init__.py +0 -0
  73. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/admin/autocomplete_filters.py +0 -0
  74. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/admin/datetime_filters.py +0 -0
  75. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/admin/dropdown_filters.py +0 -0
  76. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/admin/text_filters.py +0 -0
  77. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/apps.py +0 -0
  78. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/forms.py +0 -0
  79. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/static/unfold/filters/css/nouislider/LICENSE +0 -0
  80. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/static/unfold/filters/css/nouislider/nouislider.min.css +0 -0
  81. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/static/unfold/filters/js/DateTimeShortcuts.js +0 -0
  82. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/static/unfold/filters/js/admin-numeric-filter.js +0 -0
  83. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/static/unfold/filters/js/nouislider/LICENSE +0 -0
  84. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/static/unfold/filters/js/nouislider/nouislider.min.js +0 -0
  85. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/static/unfold/filters/js/wnumb/LICENSE +0 -0
  86. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/static/unfold/filters/js/wnumb/wNumb.min.js +0 -0
  87. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_date_range.html +0 -0
  88. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_datetime_range.html +0 -0
  89. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_field.html +0 -0
  90. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_range.html +0 -0
  91. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_single.html +0 -0
  92. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html +0 -0
  93. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/__init__.py +0 -0
  94. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/apps.py +0 -0
  95. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/static/unfold/forms/css/trix/LICENSE +0 -0
  96. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/static/unfold/forms/css/trix/trix.css +0 -0
  97. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix/LICENSE +0 -0
  98. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix/trix.js +0 -0
  99. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/static/unfold/forms/js/trix.config.js +0 -0
  100. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/templates/unfold/forms/array.html +0 -0
  101. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/templates/unfold/forms/helpers/toolbar.html +0 -0
  102. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/forms/templates/unfold/forms/wysiwyg.html +0 -0
  103. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/guardian/__init__.py +0 -0
  104. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/guardian/apps.py +0 -0
  105. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/change_form.html +0 -0
  106. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/field.html +0 -0
  107. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage.html +0 -0
  108. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_group.html +0 -0
  109. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_user.html +0 -0
  110. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/guardian/templates/unfold/guardian/group_form.html +0 -0
  111. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/guardian/templates/unfold/guardian/user_form.html +0 -0
  112. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/__init__.py +0 -0
  113. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/apps.py +0 -0
  114. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/forms.py +0 -0
  115. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/base.html +0 -0
  116. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_form.html +0 -0
  117. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_export.html +0 -0
  118. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_export_item.html +0 -0
  119. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import.html +0 -0
  120. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import_export.html +0 -0
  121. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/change_list_import_item.html +0 -0
  122. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/export.html +0 -0
  123. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/import.html +0 -0
  124. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_confirm.html +0 -0
  125. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_errors.html +0 -0
  126. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_form.html +0 -0
  127. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_preview.html +0 -0
  128. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/import_validation.html +0 -0
  129. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/import_export/templates/admin/import_export/resource_fields_list.html +0 -0
  130. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/inlines/__init__.py +0 -0
  131. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/inlines/apps.py +0 -0
  132. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/inlines/checks.py +0 -0
  133. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/location_field/__init__.py +0 -0
  134. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/location_field/apps.py +0 -0
  135. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/location_field/templates/location_field/map_widget.html +0 -0
  136. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/simple_history/__init__.py +0 -0
  137. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/simple_history/apps.py +0 -0
  138. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/simple_history/templates/simple_history/object_history.html +0 -0
  139. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/simple_history/templates/simple_history/object_history_form.html +0 -0
  140. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/simple_history/templates/simple_history/object_history_list.html +0 -0
  141. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/contrib/simple_history/templates/simple_history/submit_line.html +0 -0
  142. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/enums.py +0 -0
  143. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/exceptions.py +0 -0
  144. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/layout.py +0 -0
  145. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/overrides.py +0 -0
  146. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/paginator.py +0 -0
  147. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/sections.py +0 -0
  148. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/admin/js/admin/RelatedObjectLookups.js +0 -0
  149. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/admin/js/inlines.js +0 -0
  150. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/css/simplebar/LICENSE +0 -0
  151. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/css/simplebar/simplebar.css +0 -0
  152. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/fonts/inter/Inter-Bold.woff2 +0 -0
  153. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/fonts/inter/Inter-Medium.woff2 +0 -0
  154. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/fonts/inter/Inter-Regular.woff2 +0 -0
  155. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/fonts/inter/Inter-SemiBold.woff2 +0 -0
  156. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/fonts/inter/LICENSE +0 -0
  157. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/fonts/inter/styles.css +0 -0
  158. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/fonts/material-symbols/LICENSE +0 -0
  159. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/fonts/material-symbols/styles.css +0 -0
  160. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/alpine/LICENSE +0 -0
  161. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/alpine/alpine.anchor.js +0 -0
  162. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/alpine/alpine.js +0 -0
  163. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/alpine/alpine.persist.js +0 -0
  164. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/alpine/alpine.resize.js +0 -0
  165. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/alpine/alpine.sort.js +0 -0
  166. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/chart/LICENSE +0 -0
  167. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/chart/chart.js +0 -0
  168. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/htmx/LICENSE +0 -0
  169. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/htmx/htmx.js +0 -0
  170. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/select2.init.js +0 -0
  171. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/simplebar/LICENSE +0 -0
  172. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/static/unfold/js/simplebar/simplebar.js +0 -0
  173. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/app_index.html +0 -0
  174. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/app_list.html +0 -0
  175. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/auth/user/add_form.html +0 -0
  176. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/auth/user/change_password.html +0 -0
  177. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/base.html +0 -0
  178. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/base_site.html +0 -0
  179. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/change_form_object_tools.html +0 -0
  180. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/change_list_object_tools.html +0 -0
  181. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/date_hierarchy.html +0 -0
  182. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/delete_confirmation.html +0 -0
  183. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/delete_selected_confirmation.html +0 -0
  184. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/filter.html +0 -0
  185. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/includes/object_delete_summary.html +0 -0
  186. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/index.html +0 -0
  187. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/login.html +0 -0
  188. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/nav_sidebar.html +0 -0
  189. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/object_history.html +0 -0
  190. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/pagination.html +0 -0
  191. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/admin/submit_line.html +0 -0
  192. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/auth/widgets/read_only_password_hash.html +0 -0
  193. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/registration/logged_out.html +0 -0
  194. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/button.html +0 -0
  195. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/card.html +0 -0
  196. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/chart/bar.html +0 -0
  197. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/chart/cohort.html +0 -0
  198. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/chart/line.html +0 -0
  199. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/container.html +0 -0
  200. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/flex.html +0 -0
  201. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/icon.html +0 -0
  202. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/layer.html +0 -0
  203. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/navigation.html +0 -0
  204. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/progress.html +0 -0
  205. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/separator.html +0 -0
  206. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/table.html +0 -0
  207. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/text.html +0 -0
  208. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/title.html +0 -0
  209. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/components/tracker.html +0 -0
  210. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/account_links.html +0 -0
  211. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/actions_row.html +0 -0
  212. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/add_link.html +0 -0
  213. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/app_list.html +0 -0
  214. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/app_list_default.html +0 -0
  215. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/attrs.html +0 -0
  216. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/boolean.html +0 -0
  217. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/breadcrumb_item.html +0 -0
  218. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/change_list_filter.html +0 -0
  219. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/change_list_filter_actions.html +0 -0
  220. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/command.html +0 -0
  221. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/command_history.html +0 -0
  222. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/command_results.html +0 -0
  223. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/delete_submit_line.html +0 -0
  224. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/display_dropdown.html +0 -0
  225. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/display_header.html +0 -0
  226. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/display_label.html +0 -0
  227. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_delete.html +0 -0
  228. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_error.html +0 -0
  229. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_heading.html +0 -0
  230. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_row.html +0 -0
  231. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/edit_inline/tabular_title.html +0 -0
  232. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/field.html +0 -0
  233. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/field_readonly.html +0 -0
  234. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/field_readonly_value.html +0 -0
  235. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/fieldset_row.html +0 -0
  236. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/fieldset_row_checkbox.html +0 -0
  237. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/fieldset_row_field.html +0 -0
  238. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/form_errors.html +0 -0
  239. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/form_label.html +0 -0
  240. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/header.html +0 -0
  241. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/header_back_button.html +0 -0
  242. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/header_title.html +0 -0
  243. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/help_text.html +0 -0
  244. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/history.html +0 -0
  245. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/label.html +0 -0
  246. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/language_form.html +0 -0
  247. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/language_switch.html +0 -0
  248. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/messages/debug.html +0 -0
  249. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/messages/error.html +0 -0
  250. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/messages/errornote.html +0 -0
  251. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/messages/info.html +0 -0
  252. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/messages/success.html +0 -0
  253. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/messages/warning.html +0 -0
  254. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/messages.html +0 -0
  255. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/navigation.html +0 -0
  256. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/navigation_header.html +0 -0
  257. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/pagination.html +0 -0
  258. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/pagination_current_item.html +0 -0
  259. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/pagination_default.html +0 -0
  260. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/pagination_ellipsis.html +0 -0
  261. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/pagination_infinite.html +0 -0
  262. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/pagination_inline.html +0 -0
  263. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/popup_header.html +0 -0
  264. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/search.html +0 -0
  265. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/search_results.html +0 -0
  266. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/shortcut.html +0 -0
  267. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/site_branding.html +0 -0
  268. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/site_dropdown.html +0 -0
  269. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/site_icon.html +0 -0
  270. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/site_logo.html +0 -0
  271. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/submit.html +0 -0
  272. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/tab_action.html +0 -0
  273. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/tab_actions.html +0 -0
  274. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/tab_list.html +0 -0
  275. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/theme_switch.html +0 -0
  276. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/unauthenticated_header.html +0 -0
  277. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/unauthenticated_title.html +0 -0
  278. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/userlinks.html +0 -0
  279. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/helpers/welcomemsg.html +0 -0
  280. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/layouts/base.html +0 -0
  281. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/layouts/base_simple.html +0 -0
  282. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/layouts/skeleton.html +0 -0
  283. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/layouts/unauthenticated.html +0 -0
  284. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/templatetags/preserve_changelist_filters.html +0 -0
  285. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/clearable_file_input.html +0 -0
  286. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/clearable_file_input_small.html +0 -0
  287. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/date.html +0 -0
  288. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/foreign_key_raw_id.html +0 -0
  289. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/radio.html +0 -0
  290. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/radio_option.html +0 -0
  291. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/range.html +0 -0
  292. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/related_widget_wrapper.html +0 -0
  293. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/select.html +0 -0
  294. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/split_datetime.html +0 -0
  295. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/split_datetime_vertical.html +0 -0
  296. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/split_money.html +0 -0
  297. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/text.html +0 -0
  298. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/textarea.html +0 -0
  299. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/time.html +0 -0
  300. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold/widgets/url.html +0 -0
  301. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/display_form.html +0 -0
  302. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/errors.html +0 -0
  303. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/errors_formset.html +0 -0
  304. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/field.html +0 -0
  305. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/inputs.html +0 -0
  306. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/attrs.html +0 -0
  307. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/baseinput.html +0 -0
  308. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/button.html +0 -0
  309. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/buttonholder.html +0 -0
  310. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/checkbox.html +0 -0
  311. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/column.html +0 -0
  312. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/div.html +0 -0
  313. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/field_errors.html +0 -0
  314. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/fieldset.html +0 -0
  315. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/fieldset_subheader.html +0 -0
  316. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/help_text.html +0 -0
  317. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/help_text_and_errors.html +0 -0
  318. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/hr.html +0 -0
  319. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/radio_checkbox_select.html +0 -0
  320. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/row.html +0 -0
  321. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/layout/table_inline_formset.html +0 -0
  322. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/uni_form.html +0 -0
  323. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/whole_uni_form.html +0 -0
  324. {django_unfold-0.67.0 → django_unfold-0.69.0}/src/unfold/templates/unfold_crispy/whole_uni_formset.html +0 -0
  325. {django_unfold-0.67.0 → django_unfold-0.69.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.69.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
 
@@ -34,7 +33,7 @@ Description-Content-Type: text/markdown
34
33
  ![Pre Commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge)
35
34
  ![Code Style - Ruff](https://img.shields.io/badge/code%20style-ruff-30173D.svg?style=for-the-badge)
36
35
 
37
- Transform your Django admin into a powerful, modern administrative interface with Unfold. This open-source theme enhances Django's default admin with beautiful design, advanced features, and developer-friendly customization options. Built on proven best practices, Unfold seamlessly integrates with your existing Django admin while providing all the tools needed to create sophisticated administrative areas that both developers and end-users will love.
36
+ Modern theme that upgrades Django admin with beautiful design, advanced features, and easy customization.
38
37
 
39
38
  - **Documentation:** The full documentation is available at [unfoldadmin.com](https://unfoldadmin.com?utm_medium=github&utm_source=unfold).
40
39
  - **Unfold:** The demo site is available at [unfoldadmin.com](https://unfoldadmin.com?utm_medium=github&utm_source=unfold).
@@ -42,56 +41,49 @@ Transform your Django admin into a powerful, modern administrative interface wit
42
41
  - **Turbo:** A Django & Next.js boilerplate implementing Unfold is available at [github.com/unfoldadmin/turbo](https://github.com/unfoldadmin/turbo?utm_medium=github&utm_source=unfold).
43
42
  - **Discord:** Join our Unfold community on [Discord](https://discord.gg/9sQj9MEbNz).
44
43
 
45
- ## Profesional tools & services
44
+ ## Profesional services
46
45
 
47
- Looking for professional help with your Django or Unfold project? We offer a range of tools and services to support your development process:
46
+ Need expert help with Django or Unfold? We offer services to support your project:
48
47
 
49
- ### Consulting services
48
+ - **Consulting**: Expert guidance on Django architecture, performance, feature development, and Unfold integration. [Learn more](https://unfoldadmin.com/consulting/?utm_medium=github&utm_source=unfold)
49
+ - **Support**: Assistance with integrating or customizing Unfold, including live 1:1 calls and implementation review. Fixed price, no ongoing commitment. [Learn more](https://unfoldadmin.com/support/?utm_medium=github&utm_source=unfold)
50
+ - **Studio**: Visually customize Django admin with own color schemes. Access a variety of dashboard templates, a password reset flow, and more. [Learn more](https://unfoldadmin.com/studio?utm_medium=github&utm_source=unfold)
50
51
 
51
- Professional consulting services for Django applications — from architecture and performance optimization to feature development and Unfold integration.
52
- Ideal for teams looking to scale, modernize, or customize their Django projects with expert support. Learn more at [unfoldadmin.com/consulting](https://unfoldadmin.com/consulting/?utm_medium=github&utm_source=unfold).
52
+ [![dashboards](https://github.com/user-attachments/assets/7c3124ab-2f59-4254-9222-8a57970f51a6)](https://unfoldadmin.com/studio?utm_medium=github&utm_source=unfold)
53
53
 
54
- ### Support package
54
+ ## Latest improvements
55
55
 
56
- If you need assistance with integrating or customizing Unfold, support packages are available. They include live 1:1 calls, implementation review, and ongoing Discord-based support fixed price, no ongoing commitment. Learn more at [unfoldadmin.com/support](https://unfoldadmin.com/support/?utm_medium=github&utm_source=unfold).
56
+ - **Datasets**: Display custom changelists on change form detail pages.
57
+ - **Command**: Offers a command palette for quick searching across all models or custom-injected data.
58
+ - **Constance**: Official `django-constance` support with a completely new design and UX improvements.
57
59
 
58
- ### Unfold Studio
60
+ ## Core features
59
61
 
60
- 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
-
62
- ## Fresh Features & Enhancements
63
-
64
- - **django-constance**: Official support with a completely new design and UX improvements
65
- - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
66
- - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form
67
- - **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
-
70
- ## Core Features & Capabilities
71
-
72
- - **Visual Interface**: Provides a modern user interface based on the Tailwind CSS framework.
62
+ - **Visual interface**: Provides a modern user interface based on the Tailwind CSS framework.
73
63
  - **Sidebar navigation**: Simplifies the creation of sidebar menus with icons, collapsible sections, and more.
74
64
  - **Dark mode support**: Includes both light and dark mode themes.
75
65
  - **Flexible actions**: Provides multiple ways to define actions throughout the admin interface.
76
66
  - **Advanced filters**: Features custom dropdowns, autocomplete, numeric, datetime, and text field filters.
77
67
  - **Dashboard tools**: Includes helpers for building custom dashboard pages.
78
68
  - **UI components**: Offers reusable interface components such as cards, buttons, and charts.
79
- - **Crispy forms**: Custom template pack for django-crispy-forms to style forms with Unfold's design system
69
+ - **Crispy forms**: Custom template pack for django-crispy-forms to style forms with Unfold's design system.
80
70
  - **WYSIWYG editor**: Built-in support for WYSIWYG editing through Trix.
81
- - **Array widget:** Built-in widget for `django.contrib.postgres.fields.ArrayField`
82
- - **Inline tabs:** Group inlines into tab navigation in the change form
83
- - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form
84
- - **Model tabs:** Allow defining custom tab navigation for models
85
- - **Fieldset tabs:** Merge multiple fieldsets into tabs in the change form
86
- - **Sortable inlines:** Allow sorting inlines by dragging and dropping
87
- - **Environment label:** Distinguish between environments by displaying a label
88
- - **Nonrelated inlines:** Display nonrelated models as inlines in the change form
89
- - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
90
- - **Favicons:** Built-in support for configuring various site favicons
91
- - **Themes:** Allow customization of color scheme, background color, border radius, and more
92
- - **Font colors:** Adjust font colors for better readability
93
- - **Changeform modes:** Display fields in compressed mode in the change form
94
- - **Language switcher:** Allow changing language directly from the admin area
71
+ - **Array widget:** Built-in widget for `django.contrib.postgres.fields.ArrayField`.
72
+ - **Inline tabs:** Group inlines into tab navigation in the change form.
73
+ - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form.
74
+ - **Model tabs:** Allow defining custom tab navigation for models.
75
+ - **Fieldset tabs:** Merge multiple fieldsets into tabs in the change form.
76
+ - **Sortable inlines:** Allow sorting inlines by dragging and dropping.
77
+ - **Command**: Offers a command palette for quick searching across all models or custom-injected data.
78
+ - **Datasets**: Custom changelists `ModelAdmin` displayed on change form detail pages.
79
+ - **Environment label:** Distinguish between environments by displaying a label.
80
+ - **Nonrelated inlines:** Display nonrelated models as inlines in the change form.
81
+ - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance.
82
+ - **Favicons:** Built-in support for configuring various site favicons.
83
+ - **Themes:** Allow customization of color scheme, background color, border radius, and more.
84
+ - **Font colors:** Adjust font colors for better readability.
85
+ - **Changeform modes:** Display fields in compressed mode in the change form.
86
+ - **Language switcher:** Allow changing language directly from the admin area.
95
87
  - **Infinite paginator:** Efficiently handle large datasets with seamless pagination that reduces server load
96
88
  - **Parallel admin:** Supports [running the default admin](https://unfoldadmin.com/blog/migrating-django-admin-unfold/?utm_medium=github&utm_source=unfold) alongside Unfold.
97
89
  - **Third-party packages:** Provides default support for multiple popular applications.
@@ -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
 
@@ -8,7 +8,7 @@
8
8
  ![Pre Commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge)
9
9
  ![Code Style - Ruff](https://img.shields.io/badge/code%20style-ruff-30173D.svg?style=for-the-badge)
10
10
 
11
- Transform your Django admin into a powerful, modern administrative interface with Unfold. This open-source theme enhances Django's default admin with beautiful design, advanced features, and developer-friendly customization options. Built on proven best practices, Unfold seamlessly integrates with your existing Django admin while providing all the tools needed to create sophisticated administrative areas that both developers and end-users will love.
11
+ Modern theme that upgrades Django admin with beautiful design, advanced features, and easy customization.
12
12
 
13
13
  - **Documentation:** The full documentation is available at [unfoldadmin.com](https://unfoldadmin.com?utm_medium=github&utm_source=unfold).
14
14
  - **Unfold:** The demo site is available at [unfoldadmin.com](https://unfoldadmin.com?utm_medium=github&utm_source=unfold).
@@ -16,56 +16,49 @@ Transform your Django admin into a powerful, modern administrative interface wit
16
16
  - **Turbo:** A Django & Next.js boilerplate implementing Unfold is available at [github.com/unfoldadmin/turbo](https://github.com/unfoldadmin/turbo?utm_medium=github&utm_source=unfold).
17
17
  - **Discord:** Join our Unfold community on [Discord](https://discord.gg/9sQj9MEbNz).
18
18
 
19
- ## Profesional tools & services
19
+ ## Profesional services
20
20
 
21
- Looking for professional help with your Django or Unfold project? We offer a range of tools and services to support your development process:
21
+ Need expert help with Django or Unfold? We offer services to support your project:
22
22
 
23
- ### Consulting services
23
+ - **Consulting**: Expert guidance on Django architecture, performance, feature development, and Unfold integration. [Learn more](https://unfoldadmin.com/consulting/?utm_medium=github&utm_source=unfold)
24
+ - **Support**: Assistance with integrating or customizing Unfold, including live 1:1 calls and implementation review. Fixed price, no ongoing commitment. [Learn more](https://unfoldadmin.com/support/?utm_medium=github&utm_source=unfold)
25
+ - **Studio**: Visually customize Django admin with own color schemes. Access a variety of dashboard templates, a password reset flow, and more. [Learn more](https://unfoldadmin.com/studio?utm_medium=github&utm_source=unfold)
24
26
 
25
- Professional consulting services for Django applications — from architecture and performance optimization to feature development and Unfold integration.
26
- Ideal for teams looking to scale, modernize, or customize their Django projects with expert support. Learn more at [unfoldadmin.com/consulting](https://unfoldadmin.com/consulting/?utm_medium=github&utm_source=unfold).
27
+ [![dashboards](https://github.com/user-attachments/assets/7c3124ab-2f59-4254-9222-8a57970f51a6)](https://unfoldadmin.com/studio?utm_medium=github&utm_source=unfold)
27
28
 
28
- ### Support package
29
+ ## Latest improvements
29
30
 
30
- If you need assistance with integrating or customizing Unfold, support packages are available. They include live 1:1 calls, implementation review, and ongoing Discord-based support fixed price, no ongoing commitment. Learn more at [unfoldadmin.com/support](https://unfoldadmin.com/support/?utm_medium=github&utm_source=unfold).
31
+ - **Datasets**: Display custom changelists on change form detail pages.
32
+ - **Command**: Offers a command palette for quick searching across all models or custom-injected data.
33
+ - **Constance**: Official `django-constance` support with a completely new design and UX improvements.
31
34
 
32
- ### Unfold Studio
35
+ ## Core features
33
36
 
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
-
36
- ## Fresh Features & Enhancements
37
-
38
- - **django-constance**: Official support with a completely new design and UX improvements
39
- - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
40
- - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form
41
- - **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
-
44
- ## Core Features & Capabilities
45
-
46
- - **Visual Interface**: Provides a modern user interface based on the Tailwind CSS framework.
37
+ - **Visual interface**: Provides a modern user interface based on the Tailwind CSS framework.
47
38
  - **Sidebar navigation**: Simplifies the creation of sidebar menus with icons, collapsible sections, and more.
48
39
  - **Dark mode support**: Includes both light and dark mode themes.
49
40
  - **Flexible actions**: Provides multiple ways to define actions throughout the admin interface.
50
41
  - **Advanced filters**: Features custom dropdowns, autocomplete, numeric, datetime, and text field filters.
51
42
  - **Dashboard tools**: Includes helpers for building custom dashboard pages.
52
43
  - **UI components**: Offers reusable interface components such as cards, buttons, and charts.
53
- - **Crispy forms**: Custom template pack for django-crispy-forms to style forms with Unfold's design system
44
+ - **Crispy forms**: Custom template pack for django-crispy-forms to style forms with Unfold's design system.
54
45
  - **WYSIWYG editor**: Built-in support for WYSIWYG editing through Trix.
55
- - **Array widget:** Built-in widget for `django.contrib.postgres.fields.ArrayField`
56
- - **Inline tabs:** Group inlines into tab navigation in the change form
57
- - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form
58
- - **Model tabs:** Allow defining custom tab navigation for models
59
- - **Fieldset tabs:** Merge multiple fieldsets into tabs in the change form
60
- - **Sortable inlines:** Allow sorting inlines by dragging and dropping
61
- - **Environment label:** Distinguish between environments by displaying a label
62
- - **Nonrelated inlines:** Display nonrelated models as inlines in the change form
63
- - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
64
- - **Favicons:** Built-in support for configuring various site favicons
65
- - **Themes:** Allow customization of color scheme, background color, border radius, and more
66
- - **Font colors:** Adjust font colors for better readability
67
- - **Changeform modes:** Display fields in compressed mode in the change form
68
- - **Language switcher:** Allow changing language directly from the admin area
46
+ - **Array widget:** Built-in widget for `django.contrib.postgres.fields.ArrayField`.
47
+ - **Inline tabs:** Group inlines into tab navigation in the change form.
48
+ - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form.
49
+ - **Model tabs:** Allow defining custom tab navigation for models.
50
+ - **Fieldset tabs:** Merge multiple fieldsets into tabs in the change form.
51
+ - **Sortable inlines:** Allow sorting inlines by dragging and dropping.
52
+ - **Command**: Offers a command palette for quick searching across all models or custom-injected data.
53
+ - **Datasets**: Custom changelists `ModelAdmin` displayed on change form detail pages.
54
+ - **Environment label:** Distinguish between environments by displaying a label.
55
+ - **Nonrelated inlines:** Display nonrelated models as inlines in the change form.
56
+ - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance.
57
+ - **Favicons:** Built-in support for configuring various site favicons.
58
+ - **Themes:** Allow customization of color scheme, background color, border radius, and more.
59
+ - **Font colors:** Adjust font colors for better readability.
60
+ - **Changeform modes:** Display fields in compressed mode in the change form.
61
+ - **Language switcher:** Allow changing language directly from the admin area.
69
62
  - **Infinite paginator:** Efficiently handle large datasets with seamless pagination that reduces server load
70
63
  - **Parallel admin:** Supports [running the default admin](https://unfoldadmin.com/blog/migrating-django-admin-unfold/?utm_medium=github&utm_source=unfold) alongside Unfold.
71
64
  - **Third-party packages:** Provides default support for multiple popular applications.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-unfold"
3
- version = "0.67.0"
3
+ version = "0.69.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
@@ -23,12 +23,17 @@ from django.utils.translation import gettext_lazy as _
23
23
  from django.views import View
24
24
 
25
25
  from unfold.checks import UnfoldModelAdminChecks
26
+ from unfold.datasets import BaseDataset
26
27
  from unfold.forms import (
27
28
  ActionForm,
28
29
  PaginationGenericInlineFormSet,
29
30
  PaginationInlineFormSet,
30
31
  )
31
- from unfold.mixins import ActionModelAdminMixin, BaseModelAdminMixin
32
+ from unfold.mixins import (
33
+ ActionModelAdminMixin,
34
+ BaseModelAdminMixin,
35
+ DatasetModelAdminMixin,
36
+ )
32
37
  from unfold.overrides import FORMFIELD_OVERRIDES_INLINE
33
38
  from unfold.typing import FieldsetsType
34
39
  from unfold.views import ChangeList
@@ -43,10 +48,14 @@ checkbox = UnfoldBooleanWidget(
43
48
  )
44
49
 
45
50
 
46
- class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
51
+ class ModelAdmin(
52
+ BaseModelAdminMixin, ActionModelAdminMixin, DatasetModelAdminMixin, BaseModelAdmin
53
+ ):
47
54
  action_form = ActionForm
48
55
  custom_urls = ()
49
56
  add_fieldsets = ()
57
+ ordering_field = None
58
+ hide_ordering_field = False
50
59
  list_horizontal_scrollbar_top = False
51
60
  list_filter_submit = False
52
61
  list_filter_sheet = True
@@ -58,6 +67,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
58
67
  change_form_after_template = None
59
68
  change_form_outer_before_template = None
60
69
  change_form_outer_after_template = None
70
+ change_form_datasets = ()
61
71
  compressed_fields = False
62
72
  readonly_preprocess_fields = {}
63
73
  warn_unsaved_form = False
@@ -72,7 +82,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
72
82
 
73
83
  for filter in self.get_list_filter(self.request):
74
84
  if (
75
- isinstance(filter, (tuple, list))
85
+ isinstance(filter, tuple | list)
76
86
  and hasattr(filter[1], "form_class")
77
87
  and hasattr(filter[1].form_class, "Media")
78
88
  ):
@@ -83,12 +93,28 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
83
93
  return media
84
94
 
85
95
  def changelist_view(
86
- self, request: HttpRequest, extra_context: Optional[dict[str, str]] = None
96
+ self, request: HttpRequest, extra_context: dict[str, str] | None = None
87
97
  ) -> TemplateResponse:
88
98
  self.request = request
99
+
100
+ if self.ordering_field and self.ordering_field not in self.list_editable:
101
+ list_editable = list(getattr(self, "list_editable", []))
102
+ list_editable.append(self.ordering_field)
103
+ self.list_editable = list_editable
104
+
89
105
  return super().changelist_view(request, extra_context)
90
106
 
91
- def get_fieldsets(self, request: HttpRequest, obj=None) -> FieldsetsType:
107
+ def get_list_display(self, request: HttpRequest) -> list[str]:
108
+ list_display = super().get_list_display(request)
109
+
110
+ if self.ordering_field and self.ordering_field not in list_display:
111
+ list_display.append(self.ordering_field)
112
+
113
+ return list_display
114
+
115
+ def get_fieldsets(
116
+ self, request: HttpRequest, obj: Model | None = None
117
+ ) -> FieldsetsType:
92
118
  if not obj and self.add_fieldsets:
93
119
  return self.add_fieldsets
94
120
  return super().get_fieldsets(request, obj)
@@ -119,7 +145,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
119
145
 
120
146
  actions_list_urls = [
121
147
  path(
122
- action.path,
148
+ f"{action.path.removesuffix('/')}/",
123
149
  wrap(action.method),
124
150
  name=action.action_name,
125
151
  )
@@ -128,7 +154,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
128
154
 
129
155
  action_detail_urls = [
130
156
  path(
131
- f"<path:object_id>/{action.path}",
157
+ f"<path:object_id>/{action.path.removesuffix('/')}/",
132
158
  wrap(action.method),
133
159
  name=action.action_name,
134
160
  )
@@ -137,7 +163,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
137
163
 
138
164
  action_row_urls = [
139
165
  path(
140
- f"<path:object_id>/{action.path}",
166
+ f"<path:object_id>/{action.path.removesuffix('/')}/",
141
167
  wrap(action.method),
142
168
  name=action.action_name,
143
169
  )
@@ -152,7 +178,7 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
152
178
  + urls
153
179
  )
154
180
 
155
- def _path_from_custom_url(self, custom_url) -> URLPattern:
181
+ def _path_from_custom_url(self, custom_url: tuple[str, str, View]) -> URLPattern:
156
182
  return path(
157
183
  custom_url[0],
158
184
  self.admin_site.admin_view(custom_url[2]),
@@ -161,13 +187,15 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
161
187
  )
162
188
 
163
189
  def get_action_choices(
164
- self, request: HttpRequest, default_choices=BLANK_CHOICE_DASH
165
- ):
190
+ self,
191
+ request: HttpRequest,
192
+ default_choices: list[tuple[str, str]] = BLANK_CHOICE_DASH,
193
+ ) -> list[tuple[str, str]]:
166
194
  default_choices = [("", _("Select action"))]
167
195
  return super().get_action_choices(request, default_choices)
168
196
 
169
197
  @display(description=mark_safe(checkbox.render("action_toggle_all", 1)))
170
- def action_checkbox(self, obj: Model):
198
+ def action_checkbox(self, obj: Model) -> str:
171
199
  return checkbox.render(helpers.ACTION_CHECKBOX_NAME, str(obj.pk))
172
200
 
173
201
  def response_change(self, request: HttpRequest, obj: Model) -> HttpResponse:
@@ -177,14 +205,14 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
177
205
  return res
178
206
 
179
207
  def response_add(
180
- self, request: HttpRequest, obj: Model, post_url_continue: Optional[str] = None
208
+ self, request: HttpRequest, obj: Model, post_url_continue: str | None = None
181
209
  ) -> HttpResponse:
182
210
  res = super().response_add(request, obj, post_url_continue)
183
211
  if "next" in request.GET:
184
212
  return redirect(request.GET["next"])
185
213
  return res
186
214
 
187
- def get_changelist(self, request, **kwargs):
215
+ def get_changelist(self, request: HttpRequest, **kwargs: Any) -> ChangeList:
188
216
  return ChangeList
189
217
 
190
218
  def get_formset_kwargs(
@@ -198,6 +226,9 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
198
226
 
199
227
  return formset_kwargs
200
228
 
229
+ def get_changeform_datasets(self, request: HttpRequest) -> list[type[BaseDataset]]:
230
+ return self.change_form_datasets
231
+
201
232
 
202
233
  class BaseInlineMixin:
203
234
  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(