django-unfold 0.54.0__py3-none-any.whl → 0.55.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. {django_unfold-0.54.0.dist-info → django_unfold-0.55.1.dist-info}/METADATA +29 -11
  2. {django_unfold-0.54.0.dist-info → django_unfold-0.55.1.dist-info}/RECORD +70 -37
  3. unfold/contrib/filters/admin/choice_filters.py +71 -32
  4. unfold/contrib/filters/admin/dropdown_filters.py +15 -1
  5. unfold/contrib/filters/admin/mixins.py +25 -0
  6. unfold/contrib/filters/forms.py +3 -3
  7. unfold/contrib/filters/static/unfold/filters/css/nouislider/LICENSE +21 -0
  8. unfold/contrib/filters/static/unfold/filters/js/nouislider/LICENSE +21 -0
  9. unfold/contrib/filters/static/unfold/filters/js/wnumb/LICENSE +9 -0
  10. unfold/contrib/filters/templates/unfold/filters/filters_date_range.html +1 -1
  11. unfold/contrib/filters/templates/unfold/filters/filters_datetime_range.html +1 -1
  12. unfold/contrib/filters/templates/unfold/filters/filters_numeric_range.html +1 -1
  13. unfold/contrib/filters/templates/unfold/filters/filters_numeric_single.html +1 -1
  14. unfold/contrib/forms/static/unfold/forms/css/trix/LICENSE +20 -0
  15. unfold/contrib/forms/static/unfold/forms/js/trix/LICENSE +20 -0
  16. unfold/contrib/forms/widgets.py +2 -2
  17. unfold/layout.py +23 -0
  18. unfold/sites.py +17 -6
  19. unfold/static/unfold/css/simplebar/LICENSE +21 -0
  20. unfold/static/unfold/css/styles.css +1 -1
  21. unfold/static/unfold/fonts/inter/LICENSE +92 -0
  22. unfold/static/unfold/fonts/material-symbols/LICENSE +202 -0
  23. unfold/static/unfold/fonts/material-symbols/Material-Symbols-Outlined.woff2 +0 -0
  24. unfold/static/unfold/js/alpine/LICENSE +21 -0
  25. unfold/static/unfold/js/alpine/alpine.js +5 -0
  26. unfold/static/unfold/js/chart/LICENSE +9 -0
  27. unfold/static/unfold/js/htmx/LICENSE +13 -0
  28. unfold/static/unfold/js/select2.init.js +4 -0
  29. unfold/static/unfold/js/simplebar/LICENSE +21 -0
  30. unfold/templates/unfold/components/button.html +1 -1
  31. unfold/templates/unfold/layouts/skeleton.html +9 -9
  32. unfold/templates/unfold/widgets/clearable_file_input.html +1 -1
  33. unfold/templates/unfold/widgets/clearable_file_input_small.html +1 -1
  34. unfold/templates/unfold_crispy/display_form.html +9 -0
  35. unfold/templates/unfold_crispy/errors.html +3 -0
  36. unfold/templates/unfold_crispy/field.html +23 -0
  37. unfold/templates/unfold_crispy/inputs.html +7 -0
  38. unfold/templates/unfold_crispy/layout/attrs.html +1 -0
  39. unfold/templates/unfold_crispy/layout/baseinput.html +9 -0
  40. unfold/templates/unfold_crispy/layout/button.html +1 -0
  41. unfold/templates/unfold_crispy/layout/buttonholder.html +3 -0
  42. unfold/templates/unfold_crispy/layout/checkbox.html +19 -0
  43. unfold/templates/unfold_crispy/layout/column.html +3 -0
  44. unfold/templates/unfold_crispy/layout/div.html +4 -0
  45. unfold/templates/unfold_crispy/layout/field_errors.html +7 -0
  46. unfold/templates/unfold_crispy/layout/fieldset.html +9 -0
  47. unfold/templates/unfold_crispy/layout/help_text.html +5 -0
  48. unfold/templates/unfold_crispy/layout/help_text_and_errors.html +3 -0
  49. unfold/templates/unfold_crispy/layout/radio_checkbox_select.html +21 -0
  50. unfold/templates/unfold_crispy/layout/row.html +3 -0
  51. unfold/templates/unfold_crispy/layout/table_inline_formset.html +100 -0
  52. unfold/templates/unfold_crispy/uni_form.html +11 -0
  53. unfold/templates/unfold_crispy/whole_uni_form.html +14 -0
  54. unfold/templatetags/unfold.py +15 -9
  55. unfold/widgets.py +86 -1
  56. unfold/static/unfold/js/alpine.js +0 -5
  57. {django_unfold-0.54.0.dist-info → django_unfold-0.55.1.dist-info}/LICENSE.md +0 -0
  58. {django_unfold-0.54.0.dist-info → django_unfold-0.55.1.dist-info}/WHEEL +0 -0
  59. /unfold/contrib/filters/static/unfold/filters/css/{nouislider.min.css → nouislider/nouislider.min.css} +0 -0
  60. /unfold/contrib/filters/static/unfold/filters/js/{nouislider.min.js → nouislider/nouislider.min.js} +0 -0
  61. /unfold/contrib/filters/static/unfold/filters/js/{wNumb.min.js → wnumb/wNumb.min.js} +0 -0
  62. /unfold/contrib/forms/static/unfold/forms/css/{trix.css → trix/trix.css} +0 -0
  63. /unfold/contrib/forms/static/unfold/forms/js/{trix.js → trix/trix.js} +0 -0
  64. /unfold/static/unfold/css/{simplebar.css → simplebar/simplebar.css} +0 -0
  65. /unfold/static/unfold/js/{alpine.anchor.js → alpine/alpine.anchor.js} +0 -0
  66. /unfold/static/unfold/js/{alpine.persist.js → alpine/alpine.persist.js} +0 -0
  67. /unfold/static/unfold/js/{alpine.resize.js → alpine/alpine.resize.js} +0 -0
  68. /unfold/static/unfold/js/{alpine.sort.js → alpine/alpine.sort.js} +0 -0
  69. /unfold/static/unfold/js/{chart.js → chart/chart.js} +0 -0
  70. /unfold/static/unfold/js/{htmx.js → htmx/htmx.js} +0 -0
  71. /unfold/static/unfold/js/{simplebar.js → simplebar/simplebar.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-unfold
3
- Version: 0.54.0
3
+ Version: 0.55.1
4
4
  Summary: Modern Django admin theme for seamless interface development
5
5
  License: MIT
6
6
  Keywords: django,admin,tailwind,theme
@@ -27,6 +27,7 @@ Description-Content-Type: text/markdown
27
27
  ## Unfold Django Admin Theme
28
28
 
29
29
  [![PyPI - Version](https://img.shields.io/pypi/v/django-unfold.svg?style=for-the-badge)](https://pypi.org/project/django-unfold/)
30
+ [![Discord](https://img.shields.io/discord/1297493955231088650?style=for-the-badge&logo=discord&logoColor=%23ffffff&color=7289da)](https://discord.gg/9sQj9MEbNz)
30
31
  [![Build](https://img.shields.io/github/actions/workflow/status/unfoldadmin/django-unfold/release.yml?style=for-the-badge)](https://github.com/unfoldadmin/django-unfold/actions?query=workflow%3Arelease)
31
32
  ![Pre Commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge)
32
33
  ![Code Style - Ruff](https://img.shields.io/badge/code%20style-ruff-30173D.svg?style=for-the-badge)
@@ -43,26 +44,31 @@ Transform your Django admin into a powerful, modern administrative interface wit
43
44
 
44
45
  Need assistance with implementing Unfold or require custom Django development? Professional consulting and development services are available to help transform your Django admin interface and enhance your web applications. Whether migrating from the native Django admin to Unfold or seeking expert technical guidance, reach out to discuss your project requirements and explore development possibilities. [Get in touch](https://unfoldadmin.com/consulting?utm_medium=github&utm_source=unfold) to learn more about available services.
45
46
 
47
+ ## Unfold Studio
48
+
49
+ Unfold Studio is a theme customizer for Django admin that helps you create a branded interface. You can customize colors, upload your logo, and adjust the style without coding. The tool is currently in development, and [you can join the waitlist](https://unfoldadmin.com/studio/) to be notified when it's available.
50
+
46
51
  ## Fresh Features & Enhancements
47
52
 
48
- - **Autocomplete filters:** Enhance filter functionality with built-in autocomplete support
53
+ - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form
54
+ - **Infinite paginator:** Efficiently handle large datasets with seamless pagination that reduces server load
55
+ - **Checkbox & radio filters:** Enhanced filter options with checkbox and radio interfaces for intuitive filtering
49
56
  - **Site dropdown:** Configurable dropdown menu in the header area for managing custom navigation links
50
57
  - **Dropdown actions:** Organize action items in customizable dropdown menus
51
- - **Custom tab navigation:** Create flexible, structured tab navigation with customizable routing
52
-
53
58
 
54
59
  ## Core Features & Capabilities
55
60
 
56
61
  - **Visual Interface**: Provides a modern user interface based on the Tailwind CSS framework.
57
- - **Sidebar Navigation**: Simplifies the creation of sidebar menus with icons, collapsible sections, and more.
58
- - **Dark Mode Support**: Includes both light and dark mode themes.
59
- - **Flexible Actions**: Provides multiple ways to define actions throughout the admin interface.
60
- - **Advanced Filters**: Features custom dropdowns, autocomplete, numeric, datetime, and text field filters.
61
- - **Dashboard Tools**: Includes helpers for building custom dashboard pages.
62
- - **UI Components**: Offers reusable interface components such as cards, buttons, and charts.
63
- - **WYSIWYG Editor**: Built-in support for WYSIWYG editing through Trix.
62
+ - **Sidebar navigation**: Simplifies the creation of sidebar menus with icons, collapsible sections, and more.
63
+ - **Dark mode support**: Includes both light and dark mode themes.
64
+ - **Flexible actions**: Provides multiple ways to define actions throughout the admin interface.
65
+ - **Advanced filters**: Features custom dropdowns, autocomplete, numeric, datetime, and text field filters.
66
+ - **Dashboard tools**: Includes helpers for building custom dashboard pages.
67
+ - **UI components**: Offers reusable interface components such as cards, buttons, and charts.
68
+ - **WYSIWYG editor**: Built-in support for WYSIWYG editing through Trix.
64
69
  - **Array widget:** Built-in widget for `django.contrib.postgres.fields.ArrayField`
65
70
  - **Inline tabs:** Group inlines into tab navigation in the change form
71
+ - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form
66
72
  - **Model tabs:** Allow defining custom tab navigation for models
67
73
  - **Fieldset tabs:** Merge multiple fieldsets into tabs in the change form
68
74
  - **Sortable inlines:** Allow sorting inlines by dragging and dropping
@@ -73,9 +79,21 @@ Need assistance with implementing Unfold or require custom Django development? P
73
79
  - **Font colors:** Adjust font colors for better readability
74
80
  - **Changeform modes:** Display fields in compressed mode in the change form
75
81
  - **Language switcher:** Allow changing language directly from the admin area
82
+ - **Infinite paginator:** Efficiently handle large datasets with seamless pagination that reduces server load
76
83
  - **Parallel admin:** Supports [running the default admin](https://unfoldadmin.com/blog/migrating-django-admin-unfold/?utm_medium=github&utm_source=unfold) alongside Unfold.
77
84
  - **Third-party packages:** Provides default support for multiple popular applications.
78
85
  - **Configuration:** Allows basic options to be changed in `settings.py`.
79
86
  - **Dependencies:** Built entirely on `django.contrib.admin`.
80
87
  - **VS Code:** Project configuration and development container included.
81
88
 
89
+ ## Credits
90
+
91
+ - **Icons**: [Material Symbols](https://github.com/google/material-design-icons) - Licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
92
+ - **Font**: [Inter](https://github.com/rsms/inter) - Licensed under the [SIL Open Font License 1.1](https://scripts.sil.org/OFL).
93
+ - **Charts**: [Chart.js](https://github.com/chartjs/Chart.js) - Licensed under the [MIT License](https://opensource.org/licenses/MIT).
94
+ - **JavaScript Framework**: [Alpine.js](https://github.com/alpinejs/alpine) - Licensed under the [MIT License](https://opensource.org/licenses/MIT).
95
+ - **AJAX calls**: [HTMX](https://htmx.org/) - Licensed under the [BSD 2-Clause License](https://opensource.org/licenses/BSD-2-Clause).
96
+ - **Custom Scrollbars**: [SimpleBar](https://github.com/Grsmto/simplebar) - Licensed under the [MIT License](https://opensource.org/licenses/MIT).
97
+ - **Range Slider**: [noUiSlider](https://github.com/leongersen/noUiSlider) - Licensed under the [MIT License](https://opensource.org/licenses/MIT).
98
+ - **Number Formatting**: [wNumb](https://github.com/leongersen/wnumb) - Licensed under the [MIT License](https://opensource.org/licenses/MIT).
99
+
@@ -7,34 +7,39 @@ unfold/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  unfold/contrib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  unfold/contrib/filters/admin/__init__.py,sha256=7pooAoA2Y9MbBL_RTJBZeIAwV5ECrOvMbe0_egoHfew,1663
9
9
  unfold/contrib/filters/admin/autocomplete_filters.py,sha256=Jh3m3iQ8YubZRQDVzHPGfpk9RulOhHkZc0N7L6KV9wc,514
10
- unfold/contrib/filters/admin/choice_filters.py,sha256=pDBGb4uAbAKgZB3ChEVRy6us20JktRtdDfCjquPJKa4,4377
10
+ unfold/contrib/filters/admin/choice_filters.py,sha256=xptxmUM9FL4xZklBOBnFR0yNlzNAZgEt3xLBtMBgQko,5575
11
11
  unfold/contrib/filters/admin/datetime_filters.py,sha256=cVari_7jsfeYxJoRBhcAUOr6v9XdtDtMuMs-S1Irafo,7757
12
- unfold/contrib/filters/admin/dropdown_filters.py,sha256=aZhBTEjtbeaOdYZK4nYRmA38usy9rhVTM4L_08MGU0I,3360
13
- unfold/contrib/filters/admin/mixins.py,sha256=iOO89KpVmKig_4RPJem2TqIwZO-ROUjGTmoDmBkgyLk,4945
12
+ unfold/contrib/filters/admin/dropdown_filters.py,sha256=aBJeutavLRocbrverAUM6mx4_kCyDWKnjcx3JRVqXuc,3837
13
+ unfold/contrib/filters/admin/mixins.py,sha256=4SiJ1Qnp-REUXOhk80zq8uW0nc2i-r8aftvSaFrpPXw,5820
14
14
  unfold/contrib/filters/admin/numeric_filters.py,sha256=8GNmesgMmMIfEZb2IrGbaBoJuvB2FpIc7wPIPBpHat4,6420
15
15
  unfold/contrib/filters/admin/text_filters.py,sha256=19cOEGpSaXafcM8QuGiYaWmNi5UIQnCXEhKG-vCTfe8,2088
16
16
  unfold/contrib/filters/apps.py,sha256=wEySJy0gMLzFLb9XNKE-RexiO05X7NaQ5QmxZyziJ_k,136
17
- unfold/contrib/filters/forms.py,sha256=8p1JKYSqzB-GkUQloy-CM3aprhtTgJhI05aCG-qSdkw,8069
18
- unfold/contrib/filters/static/unfold/filters/css/nouislider.min.css,sha256=rddL_jOGGVEY6wR-aw0VYovAfz5fPeAIsulrlSNb1hc,4221
17
+ unfold/contrib/filters/forms.py,sha256=xROYON0ZaTLOE7gIhHXEgDAcYz0eY6LO2uxc3oXzfcA,8097
18
+ unfold/contrib/filters/static/unfold/filters/css/nouislider/LICENSE,sha256=DR_G6Ykr-xlGx4DwQFeKTRcGAYL3ch33e44GisGdHOQ,1069
19
+ unfold/contrib/filters/static/unfold/filters/css/nouislider/nouislider.min.css,sha256=rddL_jOGGVEY6wR-aw0VYovAfz5fPeAIsulrlSNb1hc,4221
19
20
  unfold/contrib/filters/static/unfold/filters/js/DateTimeShortcuts.js,sha256=jgFNBDf6aHvUlyv0LEDHggXO-xA8pWOCWFWcVupdA30,19332
20
21
  unfold/contrib/filters/static/unfold/filters/js/admin-numeric-filter.js,sha256=nTkiiJk4Abn9d6KigxPSEsereFhFq-v5n_boiiY1eII,1668
21
- unfold/contrib/filters/static/unfold/filters/js/nouislider.min.js,sha256=aIEt5UlLNnEv4-HPyxcLqu9dTS7gXiMm35Mm0rFmQ0Q,26683
22
- unfold/contrib/filters/static/unfold/filters/js/wNumb.min.js,sha256=gayD3el5iizhy0DlsyKfZvfOfOZHDmb7BPvOcT97GSg,2236
23
- unfold/contrib/filters/templates/unfold/filters/filters_date_range.html,sha256=PeY1O1YiqjFHt4iExWTf1084uHS6bLVHFWe_reCigqk,673
24
- unfold/contrib/filters/templates/unfold/filters/filters_datetime_range.html,sha256=PeY1O1YiqjFHt4iExWTf1084uHS6bLVHFWe_reCigqk,673
22
+ unfold/contrib/filters/static/unfold/filters/js/nouislider/LICENSE,sha256=DR_G6Ykr-xlGx4DwQFeKTRcGAYL3ch33e44GisGdHOQ,1069
23
+ unfold/contrib/filters/static/unfold/filters/js/nouislider/nouislider.min.js,sha256=aIEt5UlLNnEv4-HPyxcLqu9dTS7gXiMm35Mm0rFmQ0Q,26683
24
+ unfold/contrib/filters/static/unfold/filters/js/wnumb/LICENSE,sha256=ifeAa0-l35lCSesni0e-3xcD2BXwP7GXG6TdQiMW16I,1069
25
+ unfold/contrib/filters/static/unfold/filters/js/wnumb/wNumb.min.js,sha256=gayD3el5iizhy0DlsyKfZvfOfOZHDmb7BPvOcT97GSg,2236
26
+ unfold/contrib/filters/templates/unfold/filters/filters_date_range.html,sha256=uoEc9ytNoYcybq7S9K-1YE0jFe-Xtk4ZUnGOyc28oXo,683
27
+ unfold/contrib/filters/templates/unfold/filters/filters_datetime_range.html,sha256=uoEc9ytNoYcybq7S9K-1YE0jFe-Xtk4ZUnGOyc28oXo,683
25
28
  unfold/contrib/filters/templates/unfold/filters/filters_field.html,sha256=UTlSZlpg-gAc_a-EJLLF0NI_ofuSHQ2kMMoAs99nL2E,164
26
- unfold/contrib/filters/templates/unfold/filters/filters_numeric_range.html,sha256=aHggmpsmwts78x-BfAApHkfOImg8NEMi1FEJZwTqveI,651
27
- unfold/contrib/filters/templates/unfold/filters/filters_numeric_single.html,sha256=fWupjTY6kInxOsm2-eEMIB3IZoslnLJmxBdOdMxO-Is,588
29
+ unfold/contrib/filters/templates/unfold/filters/filters_numeric_range.html,sha256=TnklQxXhe17UaImoiHahhtN6d1xVdXt2dhIMQESJY68,661
30
+ unfold/contrib/filters/templates/unfold/filters/filters_numeric_single.html,sha256=uELVrDzFgmzGwkm37SpZeXXbfpijDnSBIJVtf6evWjM,598
28
31
  unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html,sha256=UDhcNnDmP9ab6UMvikRp7tNVQazoh_fUds29yhWOljs,1724
29
32
  unfold/contrib/forms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
33
  unfold/contrib/forms/apps.py,sha256=Di0TMzVuRpVxLG-8Bjdq5ALCSf5r7u2xVhD0jU6H5Sc,132
31
- unfold/contrib/forms/static/unfold/forms/css/trix.css,sha256=TH9WdnaZrmwI8hAEydwjobdrBzSw_KYdRTSQDuD-8hE,20027
34
+ unfold/contrib/forms/static/unfold/forms/css/trix/LICENSE,sha256=-g0UVDdcvHcBvBPZFsOuceYTuK5xgyFkHmeOCUCTk8Q,1053
35
+ unfold/contrib/forms/static/unfold/forms/css/trix/trix.css,sha256=TH9WdnaZrmwI8hAEydwjobdrBzSw_KYdRTSQDuD-8hE,20027
36
+ unfold/contrib/forms/static/unfold/forms/js/trix/LICENSE,sha256=-g0UVDdcvHcBvBPZFsOuceYTuK5xgyFkHmeOCUCTk8Q,1053
37
+ unfold/contrib/forms/static/unfold/forms/js/trix/trix.js,sha256=HJXkWw7Mtocr7IeyBVplEIeO4X0kUhHHsI1Yra_ZMl8,175599
32
38
  unfold/contrib/forms/static/unfold/forms/js/trix.config.js,sha256=spkNBlJVk_pqido_rM6yywQxkJ3Kqb7DMLiBgpKksdA,858
33
- unfold/contrib/forms/static/unfold/forms/js/trix.js,sha256=HJXkWw7Mtocr7IeyBVplEIeO4X0kUhHHsI1Yra_ZMl8,175599
34
39
  unfold/contrib/forms/templates/unfold/forms/array.html,sha256=utd_6pwpIDAP2WWg9uXofZzyuunk_u-x7EL7L-v5H-0,1779
35
40
  unfold/contrib/forms/templates/unfold/forms/helpers/toolbar.html,sha256=wK4yPTuKLmKdr_zonhksD3qONtbzchV19baIk6mqTXk,9746
36
41
  unfold/contrib/forms/templates/unfold/forms/wysiwyg.html,sha256=uLLf59jsD3apAm9Uh1TH4pwCOtO7pL2djAeZLOHyNAI,399
37
- unfold/contrib/forms/widgets.py,sha256=YiG6jRrVWMNW3NGAbqvm68FgcdTKyforROmhL7oAK9U,3127
42
+ unfold/contrib/forms/widgets.py,sha256=n10qDRv2yeYTOHc7ch2HxKzKcCnmgS8sg-YIAJp7xrY,3137
38
43
  unfold/contrib/guardian/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
44
  unfold/contrib/guardian/apps.py,sha256=ObJqwh4vHxkD4XfduP5IQAiYiWZxsXUOUqF1_R1GsRI,136
40
45
  unfold/contrib/guardian/templates/admin/guardian/model/change_form.html,sha256=FSJc4MYYWyzZAy8Ay0b7Ov-cUo-oELHOM5fQehM54Lg,403
@@ -78,6 +83,7 @@ unfold/enums.py,sha256=9sTfyEycMWeoGPBa-ft6ZhQGnW1vkFg108RMBVf9nko,187
78
83
  unfold/exceptions.py,sha256=gcCj1ox61E137bk_0Cqy4YC3SttdPgB-fiJUqpmyHSE,43
79
84
  unfold/fields.py,sha256=J3goIMlP_XOmQ85Xgh2v5MylXSP1o5I7o9_So2FQn2k,7461
80
85
  unfold/forms.py,sha256=3MrVG9jDdDsrJHph-cimZXRycfdoAw-KhT0uJJInG7E,4552
86
+ unfold/layout.py,sha256=idG4v0AumFPyy16KUlKtWrs9kyBQIKY_Ln26Lx9DOPg,501
81
87
  unfold/mixins/__init__.py,sha256=YlhoDs9Y_DXQ8Ejr3enxuHMS1-Ij9fwukxNwpeOS4Co,190
82
88
  unfold/mixins/action_model_admin.py,sha256=BPajuTGf7zAaZOqIq4shX8VQ3NTxWQpedvG58fmCTjk,12036
83
89
  unfold/mixins/base_model_admin.py,sha256=PR4eqU48yB4CNy9Bjd7fjxbOFiFpZM4etYmBOSaRX_M,4140
@@ -85,28 +91,35 @@ unfold/overrides.py,sha256=ERVY9boZiXgjDYcTEZcIp7KWoeBZ45VM_zN31yAOjyQ,2922
85
91
  unfold/paginator.py,sha256=vWCIfpuWbV3nvIkQOPyD7MLTg2hZplHz3rze42d-qiA,268
86
92
  unfold/sections.py,sha256=Lcg3xCZ76fqjm4vD4x7YdE5VsbTKluL-sX5QTEBlHxA,2379
87
93
  unfold/settings.py,sha256=3ICha2I0oSaHhajG8159nHdNTYJInBtRQq9VziWKYKs,2709
88
- unfold/sites.py,sha256=fx3U0kIfN3My4UNiXO_ggrudmFvYNglMAIARaMa2gqY,16321
94
+ unfold/sites.py,sha256=n1IY7xS4316ZfjcwKWQlnkPtzdVCifbltBT-yZoUu3k,16657
89
95
  unfold/static/admin/js/admin/RelatedObjectLookups.js,sha256=alI0-yq7YPDJJJn-yg1ce79-Cv88yQDUrfaGqFZnsaY,9048
90
96
  unfold/static/admin/js/inlines.js,sha256=zcYwLGI_6RHg-gucDbbhp43RRoZd3so8bPk841KFaIE,15573
91
- unfold/static/unfold/css/simplebar.css,sha256=5LLaEM11pKi6JFCOLt4XKuZxTpT9rpdq_tNlaQytFlU,4647
92
- unfold/static/unfold/css/styles.css,sha256=-tB48trW_4YUmPdnHYP31ulsXOPiwsC6s6hHffmDW_w,161933
97
+ unfold/static/unfold/css/simplebar/LICENSE,sha256=okNJf6UFl2NrEiC4iqORNBa16IKgUgV88acdcl9FbtY,1081
98
+ unfold/static/unfold/css/simplebar/simplebar.css,sha256=5LLaEM11pKi6JFCOLt4XKuZxTpT9rpdq_tNlaQytFlU,4647
99
+ unfold/static/unfold/css/styles.css,sha256=LolJmXEJUWR42aC7fNQLhfoQZBSzTE9vD-1bynfFeGo,162977
93
100
  unfold/static/unfold/fonts/inter/Inter-Bold.woff2,sha256=-oiBJ7baAVtlVp8DUfO1w5GtkokElR8cIOn4RiqNleo,114840
94
101
  unfold/static/unfold/fonts/inter/Inter-Medium.woff2,sha256=D_PpRhThST61VjFP0keubEqFp3g7TMhr5TmUDPg_Kkg,114348
95
102
  unfold/static/unfold/fonts/inter/Inter-Regular.woff2,sha256=4G9rG8VTqupORmgCPtCrChRxKcMQf1Ebx9A9NhsK4IU,111268
96
103
  unfold/static/unfold/fonts/inter/Inter-SemiBold.woff2,sha256=XLcQPk5gWYmv68A9mJx5IB5UshtRg9szmB9w25F4owE,114812
104
+ unfold/static/unfold/fonts/inter/LICENSE,sha256=JiSB6ERSGzJvXs0FPlm5jIstp4yO4b27boF0MF5Uk1o,4380
97
105
  unfold/static/unfold/fonts/inter/styles.css,sha256=QqdgevXVfcD6vZGo8ciSkaEG_62_YcZg0hvHTNgJ56E,608
98
- unfold/static/unfold/fonts/material-symbols/Material-Symbols-Outlined.woff2,sha256=V6mmjk69Ee-coQvMsGV0tcNgV3E1nb7N9IKW8HVUBzk,256424
106
+ unfold/static/unfold/fonts/material-symbols/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
107
+ unfold/static/unfold/fonts/material-symbols/Material-Symbols-Outlined.woff2,sha256=sMDmadC_mJOI200LuWcwAZRwAqDWLgdj85JA0x42qu8,274228
99
108
  unfold/static/unfold/fonts/material-symbols/styles.css,sha256=ZX1icA_BXCVL0eoY2H6XR8VT_Fxl_KnV6vFBm_OImHA,535
100
- unfold/static/unfold/js/alpine.anchor.js,sha256=2Jg9aUq749pjFynzr_H1NK3lf-nXrbHMtO9wvlWJyIQ,15524
101
- unfold/static/unfold/js/alpine.js,sha256=NY2a-7GrW--i9IBhowd25bzXcH9BCmBrqYX5i8OxwDQ,44659
102
- unfold/static/unfold/js/alpine.persist.js,sha256=jFBwr6faTqqhp3sVi4_VTxJ0FpaF9YGZN1ZGLl_5QYM,837
103
- unfold/static/unfold/js/alpine.resize.js,sha256=mXR2L6neT584cfNLY5_imDq5DKjW1noXys7fhb1yxY4,703
104
- unfold/static/unfold/js/alpine.sort.js,sha256=q6LxgConwu8M8R03mZSBcsKwJv6fF7oomP8sqLxVQ0w,37891
109
+ unfold/static/unfold/js/alpine/LICENSE,sha256=XwXEkl3T7fBJpwtLQDrA3UOyD3JQHZNZkR3dJdWsZX0,1092
110
+ unfold/static/unfold/js/alpine/alpine.anchor.js,sha256=2Jg9aUq749pjFynzr_H1NK3lf-nXrbHMtO9wvlWJyIQ,15524
111
+ unfold/static/unfold/js/alpine/alpine.js,sha256=PtHu0lJIiSHfZeNj1nFd6wTX-Squ255SGZ_fc8seCtM,44758
112
+ unfold/static/unfold/js/alpine/alpine.persist.js,sha256=jFBwr6faTqqhp3sVi4_VTxJ0FpaF9YGZN1ZGLl_5QYM,837
113
+ unfold/static/unfold/js/alpine/alpine.resize.js,sha256=mXR2L6neT584cfNLY5_imDq5DKjW1noXys7fhb1yxY4,703
114
+ unfold/static/unfold/js/alpine/alpine.sort.js,sha256=q6LxgConwu8M8R03mZSBcsKwJv6fF7oomP8sqLxVQ0w,37891
105
115
  unfold/static/unfold/js/app.js,sha256=mxCSV8gZvRLHab-_Xm_229NtQ9IX-59vS_GKWTp9liM,7748
106
- unfold/static/unfold/js/chart.js,sha256=22W6cFERR-CElMOKRgMMicueMVP0Vf7FBEBYH8Z8tCk,200633
107
- unfold/static/unfold/js/htmx.js,sha256=acrv0NqSJpBm5yXX_hdeJrnVDJYuMFZFnAxHcVTNudM,50918
108
- unfold/static/unfold/js/select2.init.js,sha256=gXZngZh-l5ID2-VmndpGseNi6A0zKB18UgPyCor68CU,1040
109
- unfold/static/unfold/js/simplebar.js,sha256=t-uG1FAD6ZoiMeN--wac0XRS7SxoDVG6zvRnGuEp7X8,27176
116
+ unfold/static/unfold/js/chart/LICENSE,sha256=QahKosq6ZF-WahjZwgVrc-bTqB2AvABGvAARomNNTM4,1093
117
+ unfold/static/unfold/js/chart/chart.js,sha256=22W6cFERR-CElMOKRgMMicueMVP0Vf7FBEBYH8Z8tCk,200633
118
+ unfold/static/unfold/js/htmx/LICENSE,sha256=09JFb3ZBTyRWEEZg69Za_xwEzXlmuUK9q9Y_PNsxajg,642
119
+ unfold/static/unfold/js/htmx/htmx.js,sha256=acrv0NqSJpBm5yXX_hdeJrnVDJYuMFZFnAxHcVTNudM,50918
120
+ unfold/static/unfold/js/select2.init.js,sha256=l0O8ggw_CkAw-QtH3qEzC8xWk0mR9QHjy4VzAjMwiQQ,1109
121
+ unfold/static/unfold/js/simplebar/LICENSE,sha256=okNJf6UFl2NrEiC4iqORNBa16IKgUgV88acdcl9FbtY,1081
122
+ unfold/static/unfold/js/simplebar/simplebar.js,sha256=t-uG1FAD6ZoiMeN--wac0XRS7SxoDVG6zvRnGuEp7X8,27176
110
123
  unfold/styles.css,sha256=Mbe0mO2608aH3bCVllxTKb6OcsMIy-ZAugcwaWBwM0E,19142
111
124
  unfold/templates/admin/actions.html,sha256=aroIid16mORcx-0p8O2dOoWupEoTGX66pt-PAXjSYZ0,3063
112
125
  unfold/templates/admin/app_index.html,sha256=GSBry97gDcK3scTP-Fs4FXcSItRxxE87Wv4sDtMTlbc,1244
@@ -139,7 +152,7 @@ unfold/templates/auth/widgets/read_only_password_hash.html,sha256=bQiYKDKJkyVP0_
139
152
  unfold/templates/registration/logged_out.html,sha256=GgLzqmOGpiw5FcA-Aw_T6YvhYHhGFWhyES40T28waLQ,1002
140
153
  unfold/templates/registration/password_change_done.html,sha256=9HDpSraz3Kxdy0Fghbn-Lv0GAtpPgG6cuO7fvfMiYg8,1077
141
154
  unfold/templates/registration/password_change_form.html,sha256=EgakVWzpQUEJKQS0AOfk8O_CY1bKbyWXSUuBaxtQEdU,2232
142
- unfold/templates/unfold/components/button.html,sha256=TABo79ppuGlm2ENvRs6L3Vne8B5_9he_OhZTnPMiitQ,473
155
+ unfold/templates/unfold/components/button.html,sha256=db7bT5aR4WXE3aJzHpKkRPGCD2UHrNgVRvZXLSHmIC4,603
143
156
  unfold/templates/unfold/components/card.html,sha256=FVLN7kQZqMd_uhEi1LpiN9FUxZCa4RgGHYGmofCtQro,1141
144
157
  unfold/templates/unfold/components/chart/bar.html,sha256=nDdDCUXvFd793OpNgNPQo0vBmvYngMsQyPHVTf1vfOw,297
145
158
  unfold/templates/unfold/components/chart/cohort.html,sha256=wDjRb2IT1XEJ--Y1BrSaMOeM7XXy9iohJR_4RZ2ilSs,2362
@@ -220,10 +233,10 @@ unfold/templates/unfold/helpers/userlinks.html,sha256=oZqiwCxG_zRecAbzYrr8_hQvkn
220
233
  unfold/templates/unfold/helpers/welcomemsg.html,sha256=uncDEg3j6NsSKCGOA7uVY-GCxsacktV3-bQrd-vn5FU,1940
221
234
  unfold/templates/unfold/layouts/base.html,sha256=e9T-vuPvrySHf23LLwRuTQXUg0Q4x-6gmT_yXghqc-I,278
222
235
  unfold/templates/unfold/layouts/base_simple.html,sha256=VigjNWnWOt_XtbahvqsroPf8mdwl7cDGbg5fEaLmG9s,1211
223
- unfold/templates/unfold/layouts/skeleton.html,sha256=TmZ0hX5j7McwSiYcdGGuhAjDunPDCWtPC7lDF6hbtDk,4641
236
+ unfold/templates/unfold/layouts/skeleton.html,sha256=28jaS_gvImuW7jfEN_akUB5qieTWCAeLw-vH_SZByAM,4707
224
237
  unfold/templates/unfold/templatetags/preserve_changelist_filters.html,sha256=sx2jUhogNY4emBhY8PqxQ6mXifbXQb_IQI9Hd0boJI0,111
225
- unfold/templates/unfold/widgets/clearable_file_input.html,sha256=4vsLRjqOmGqdU4aPSq81rc-mdRvpBr-H_bC5ScyUkEY,2231
226
- unfold/templates/unfold/widgets/clearable_file_input_small.html,sha256=NNlosUwhzv-3SZH9LdliL5c6fdoVNRb1JP0uHwFV-N8,2849
238
+ unfold/templates/unfold/widgets/clearable_file_input.html,sha256=3C4N7OZaiQILNahs12NotNxlQ5QInaXVQtMR4bekHw8,2149
239
+ unfold/templates/unfold/widgets/clearable_file_input_small.html,sha256=FkjdsrkrBa0GxmY3RNZoU08Xs5aDrOD4Q8fU8VbY_vU,2574
227
240
  unfold/templates/unfold/widgets/date.html,sha256=ih9wj8koTaHb9s1NGUmyN9rHvSAmqCMbti9ONDOIujg,122
228
241
  unfold/templates/unfold/widgets/foreign_key_raw_id.html,sha256=7-JPapXS2Ty0MLXNdZ1jCuydqc6JyDs-8-w9b8TcmVU,1075
229
242
  unfold/templates/unfold/widgets/radio.html,sha256=7Mgc92mMwJdVLjCxoGj5lo76KNaN5dKKktV3vzmbeqA,652
@@ -236,14 +249,34 @@ unfold/templates/unfold/widgets/split_money.html,sha256=AFLUBmzGbY-RXgsfz7gaDxVR
236
249
  unfold/templates/unfold/widgets/textarea.html,sha256=-ZLDGrtASero7L-J3VvTNq_KjPAZh_kLVw0Ow3awqXM,144
237
250
  unfold/templates/unfold/widgets/time.html,sha256=ih9wj8koTaHb9s1NGUmyN9rHvSAmqCMbti9ONDOIujg,122
238
251
  unfold/templates/unfold/widgets/url.html,sha256=IRLgW44VTKN7UrSWeywJwaxQhfG5jhhXuT-KTadKX58,304
252
+ unfold/templates/unfold_crispy/display_form.html,sha256=tGyr8hvMlnKkm2ILbVj0enj6IrjtqiKo6nO9Z-zHE2Q,270
253
+ unfold/templates/unfold_crispy/errors.html,sha256=bzTXuZh_UkQLb4sPaa0En5Uopveoe573TaEOM9OQVcw,132
254
+ unfold/templates/unfold_crispy/field.html,sha256=7Q55yPp0-lkIF2v916GNJbjWjaRlQSvlLJ6KvG9TabI,1610
255
+ unfold/templates/unfold_crispy/inputs.html,sha256=GFOh6U3XzZJvUAZ4_V9Jrbm3FusI5flWzT_sEWLn8tI,294
256
+ unfold/templates/unfold_crispy/layout/attrs.html,sha256=LsLlfKenzHKl6n25m4Ers2NepLSA_RBy9AqezKZ7rH8,173
257
+ unfold/templates/unfold_crispy/layout/baseinput.html,sha256=GjMxXoqpnxCPkPC1E3v_crzlxDb_hHMf_UgJYfqSsYE,440
258
+ unfold/templates/unfold_crispy/layout/button.html,sha256=evlO80en9FkbW3UayLPTNUZXAYvgr3slSAsGPKXs96M,67
259
+ unfold/templates/unfold_crispy/layout/buttonholder.html,sha256=ruHqViROk7nh4luckA8-mcfmnYBqsVM85e8j0rOi3cU,415
260
+ unfold/templates/unfold_crispy/layout/checkbox.html,sha256=DT3zJIUCDuGJ-gxaaNgHUSWfU7oWyk5lvJPREGv830w,732
261
+ unfold/templates/unfold_crispy/layout/column.html,sha256=Bob4xRcbJOHScDjSjLMRIMNf4lonNmm8F_JOm2azTik,172
262
+ unfold/templates/unfold_crispy/layout/div.html,sha256=RE9qQ2w2I2zpi7Z7xzVmVO03UXq0yZvMw-W7rVJkEdw,174
263
+ unfold/templates/unfold_crispy/layout/field_errors.html,sha256=pEn-c6Bfdg54vRm2FxmM8BGbvN0O2R92bnj_gL81X_Q,274
264
+ unfold/templates/unfold_crispy/layout/fieldset.html,sha256=nfIp48NjAJUyNYHkrY7LLEvdgm9rkbytupqzLWTgkFc,581
265
+ unfold/templates/unfold_crispy/layout/help_text.html,sha256=FY0UQv5FsoOFhrqvbILEfZE78Hj30r73YHCtg_MWNeY,207
266
+ unfold/templates/unfold_crispy/layout/help_text_and_errors.html,sha256=Um14wIg0FHthNM0mKE9VdptTrC-lTTcrDUO-UbbXxhY,108
267
+ unfold/templates/unfold_crispy/layout/radio_checkbox_select.html,sha256=pUlHC6j-fH62fAMiAZW-4BWXGD0RocHOKCmLtHN9pP8,997
268
+ unfold/templates/unfold_crispy/layout/row.html,sha256=MgGCI9s2mEn8C6xc78fb2Y4BsW6sbsKvgEd6aVRlFsg,184
269
+ unfold/templates/unfold_crispy/layout/table_inline_formset.html,sha256=QkKQU54uPTtFH58waipszk4SsQQw6mnBEqrzqgNsbls,4557
270
+ unfold/templates/unfold_crispy/uni_form.html,sha256=l9UNCUrIycgJ0p_B6qhtO_YxdARy3aq8qYY5h5BheSo,312
271
+ unfold/templates/unfold_crispy/whole_uni_form.html,sha256=ufXRKCIGqkqKFOsh166rpKUnHpFMyBV4eYUCRhs3iws,475
239
272
  unfold/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
240
- unfold/templatetags/unfold.py,sha256=yPSNtaBDiiJh6VNhl3VPDJ-jsX69pbnIf4JolEnw290,16239
273
+ unfold/templatetags/unfold.py,sha256=FcP69QNQ2_CPeqESvbxNax_VRw3WAE_R8Bjdkn4ZJuQ,16581
241
274
  unfold/templatetags/unfold_list.py,sha256=ayShOYEXcV3o7wKt3t2aFTWvg62Mb-WGlxjYVGgk3a0,14344
242
275
  unfold/typing.py,sha256=i7LM2LiwYTAjT5-OLDUPVn5b9X-DMmHnjlZG2toWwSE,692
243
276
  unfold/utils.py,sha256=SJikRuAuJN0bE9rfzUujZwycTRrzQm14Hk0zB0EwivU,6164
244
277
  unfold/views.py,sha256=FuYnMrlg6SegLUDDN6An__yZj8rchD_iBK8myieYhkA,1492
245
- unfold/widgets.py,sha256=1uyGsw-xA0qspf7Uzic47GVN5xv4L_sVfL-elqlxgm0,20293
246
- django_unfold-0.54.0.dist-info/LICENSE.md,sha256=Ltk_quRyyvV3J5v3brtOqmibeZSw2Hrb8bY1W3ya0Ik,1077
247
- django_unfold-0.54.0.dist-info/METADATA,sha256=jKgXXRccydhPXLehmUQkHA_xcBzY2XulaY2fB04a_NA,5929
248
- django_unfold-0.54.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
249
- django_unfold-0.54.0.dist-info/RECORD,,
278
+ unfold/widgets.py,sha256=-l0eRljJheVWhTtD0nTvNuY1dvNmwtfd-aqXdSVr-q0,22344
279
+ django_unfold-0.55.1.dist-info/LICENSE.md,sha256=Ltk_quRyyvV3J5v3brtOqmibeZSw2Hrb8bY1W3ya0Ik,1077
280
+ django_unfold-0.55.1.dist-info/METADATA,sha256=t0DhmEvjtNDYPVLS_fO_1pGZSp-9BWhGe1rrL4_zmPI,7951
281
+ django_unfold-0.55.1.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
282
+ django_unfold-0.55.1.dist-info/RECORD,,
@@ -8,7 +8,11 @@ from django.db.models import QuerySet
8
8
  from django.http import HttpRequest
9
9
  from django.utils.translation import gettext_lazy as _
10
10
 
11
- from unfold.contrib.filters.admin.mixins import MultiValueMixin, ValueMixin
11
+ from unfold.contrib.filters.admin.mixins import (
12
+ ChoicesMixin,
13
+ MultiValueMixin,
14
+ ValueMixin,
15
+ )
12
16
  from unfold.contrib.filters.forms import CheckboxForm, HorizontalRadioForm, RadioForm
13
17
 
14
18
 
@@ -18,10 +22,23 @@ class RadioFilter(admin.SimpleListFilter):
18
22
  all_option = ["", _("All")]
19
23
 
20
24
  def choices(self, changelist: ChangeList) -> tuple[dict[str, Any], ...]:
25
+ add_facets = changelist.add_facets
26
+ facet_counts = self.get_facet_queryset(changelist) if add_facets else None
27
+ choices = []
28
+
21
29
  if self.all_option:
22
- choices = [self.all_option, *self.lookup_choices]
30
+ choices = [self.all_option]
31
+
32
+ if add_facets:
33
+ for i, (lookup, title) in enumerate(self.lookup_choices):
34
+ if (count := facet_counts.get(f"{i}__c", -1)) != -1:
35
+ title = f"{title} ({count})"
36
+ else:
37
+ title = f"{title} (-)"
38
+
39
+ choices.append((lookup, title))
23
40
  else:
24
- choices = self.lookup_choices
41
+ choices.extend(self.lookup_choices)
25
42
 
26
43
  return (
27
44
  {
@@ -39,24 +56,8 @@ class CheckboxFilter(RadioFilter):
39
56
  form_class = CheckboxForm
40
57
  all_option = None
41
58
 
42
-
43
- class ChoicesMixin:
44
- template = "unfold/filters/filters_field.html"
45
-
46
- def choices(self, changelist: ChangeList) -> Generator[dict[str, Any], None, None]:
47
- if self.all_option:
48
- choices = [self.all_option, *self.field.flatchoices]
49
- else:
50
- choices = self.field.flatchoices
51
-
52
- yield {
53
- "form": self.form_class(
54
- label=_(" By %(filter_title)s ") % {"filter_title": self.title},
55
- name=self.lookup_kwarg,
56
- choices=choices,
57
- data={self.lookup_kwarg: self.value()},
58
- ),
59
- }
59
+ def value(self) -> list[Any]:
60
+ return self.request.GET.getlist(self.parameter_name)
60
61
 
61
62
 
62
63
  class ChoicesRadioFilter(ValueMixin, ChoicesMixin, admin.ChoicesFieldListFilter):
@@ -64,7 +65,9 @@ class ChoicesRadioFilter(ValueMixin, ChoicesMixin, admin.ChoicesFieldListFilter)
64
65
  all_option = ["", _("All")]
65
66
 
66
67
 
67
- class ChoicesCheckboxFilter(ValueMixin, ChoicesMixin, admin.ChoicesFieldListFilter):
68
+ class ChoicesCheckboxFilter(
69
+ MultiValueMixin, ChoicesMixin, admin.ChoicesFieldListFilter
70
+ ):
68
71
  form_class = CheckboxForm
69
72
  all_option = None
70
73
 
@@ -75,13 +78,25 @@ class BooleanRadioFilter(ValueMixin, admin.BooleanFieldListFilter):
75
78
  all_option = ["", _("All")]
76
79
 
77
80
  def choices(self, changelist: ChangeList) -> Generator[dict[str, Any], None, None]:
78
- choices = [
79
- self.all_option,
80
- *[
81
- ("1", _("Yes")),
82
- ("0", _("No")),
83
- ],
84
- ]
81
+ add_facets = changelist.add_facets
82
+ facet_counts = self.get_facet_queryset(changelist) if add_facets else None
83
+
84
+ if add_facets:
85
+ choices = [
86
+ self.all_option,
87
+ *[
88
+ ("1", f"{_('Yes')} ({facet_counts['true__c']})"),
89
+ ("0", f"{_('No')} ({facet_counts['false__c']})"),
90
+ ],
91
+ ]
92
+ else:
93
+ choices = [
94
+ self.all_option,
95
+ *[
96
+ ("1", _("Yes")),
97
+ ("0", _("No")),
98
+ ],
99
+ ]
85
100
 
86
101
  yield {
87
102
  "form": self.form_class(
@@ -104,11 +119,24 @@ class RelatedCheckboxFilter(MultiValueMixin, admin.RelatedFieldListFilter):
104
119
  return queryset
105
120
 
106
121
  def choices(self, changelist: ChangeList) -> Generator[dict[str, Any], None, None]:
122
+ add_facets = changelist.add_facets
123
+ facet_counts = self.get_facet_queryset(changelist) if add_facets else None
124
+
125
+ if add_facets:
126
+ choices = []
127
+
128
+ for pk_val, val in self.lookup_choices:
129
+ count = facet_counts[f"{pk_val}__c"]
130
+ choice = (pk_val, f"{val} ({count})")
131
+ choices.append(choice)
132
+ else:
133
+ choices = self.lookup_choices
134
+
107
135
  yield {
108
136
  "form": self.form_class(
109
137
  label=_(" By %(filter_title)s ") % {"filter_title": self.title},
110
138
  name=self.lookup_kwarg,
111
- choices=self.lookup_choices,
139
+ choices=choices,
112
140
  data={self.lookup_kwarg: self.value()},
113
141
  ),
114
142
  }
@@ -119,7 +147,18 @@ class AllValuesCheckboxFilter(MultiValueMixin, admin.AllValuesFieldListFilter):
119
147
  form_class = CheckboxForm
120
148
 
121
149
  def choices(self, changelist: ChangeList) -> Generator[dict[str, Any], None, None]:
122
- choices = [[i, val] for i, val in enumerate(self.lookup_choices)]
150
+ add_facets = changelist.add_facets
151
+ facet_counts = self.get_facet_queryset(changelist) if add_facets else None
152
+
153
+ if add_facets:
154
+ choices = []
155
+
156
+ for i, val in enumerate(self.lookup_choices):
157
+ count = facet_counts[f"{i}__c"]
158
+ choice = (val, f"{val} ({count})")
159
+ choices.append(choice)
160
+ else:
161
+ choices = [[val, val] for _i, val in enumerate(self.lookup_choices)]
123
162
 
124
163
  if len(choices) == 0:
125
164
  return
@@ -128,7 +167,7 @@ class AllValuesCheckboxFilter(MultiValueMixin, admin.AllValuesFieldListFilter):
128
167
  "form": self.form_class(
129
168
  label=_(" By %(filter_title)s ") % {"filter_title": self.title},
130
169
  name=self.lookup_kwarg,
131
- choices=[[i, val] for i, val in enumerate(self.lookup_choices)],
170
+ choices=choices,
132
171
  data={self.lookup_kwarg: self.value()},
133
172
  ),
134
173
  }
@@ -86,11 +86,25 @@ class RelatedDropdownFilter(ValueMixin, DropdownMixin, admin.RelatedFieldListFil
86
86
  self.request = request
87
87
 
88
88
  def choices(self, changelist: ChangeList) -> Generator[dict[str, Any], None, None]:
89
+ add_facets = changelist.add_facets
90
+ facet_counts = self.get_facet_queryset(changelist) if add_facets else None
91
+
92
+ if add_facets:
93
+ choices = [self.all_option]
94
+
95
+ for pk_val, val in self.lookup_choices:
96
+ if add_facets:
97
+ count = facet_counts[f"{pk_val}__c"]
98
+ choice = (pk_val, f"{val} ({count})")
99
+ choices.append(choice)
100
+ else:
101
+ choices = [self.all_option, *self.lookup_choices]
102
+
89
103
  yield {
90
104
  "form": self.form_class(
91
105
  label=_(" By %(filter_title)s ") % {"filter_title": self.title},
92
106
  name=self.lookup_kwarg,
93
- choices=[self.all_option, *self.lookup_choices],
107
+ choices=choices,
94
108
  data={self.lookup_kwarg: self.value()},
95
109
  multiple=self.multiple if hasattr(self, "multiple") else False,
96
110
  ),
@@ -51,6 +51,31 @@ class DropdownMixin:
51
51
  return queryset
52
52
 
53
53
 
54
+ class ChoicesMixin:
55
+ template = "unfold/filters/filters_field.html"
56
+
57
+ def choices(self, changelist: ChangeList) -> Generator[dict[str, Any], None, None]:
58
+ add_facets = changelist.add_facets
59
+ facet_counts = self.get_facet_queryset(changelist) if add_facets else None
60
+ choices = [self.all_option] if self.all_option else []
61
+
62
+ for i, choice in enumerate(self.field.flatchoices):
63
+ if add_facets:
64
+ count = facet_counts[f"{i}__c"]
65
+ choice = (choice[0], f"{choice[1]} ({count})")
66
+
67
+ choices.append(choice)
68
+
69
+ yield {
70
+ "form": self.form_class(
71
+ label=_(" By %(filter_title)s ") % {"filter_title": self.title},
72
+ name=self.lookup_kwarg,
73
+ choices=choices,
74
+ data={self.lookup_kwarg: self.value()},
75
+ ),
76
+ }
77
+
78
+
54
79
  class RangeNumericMixin:
55
80
  request = None
56
81
  parameter_name = None
@@ -197,10 +197,10 @@ class RangeNumericForm(forms.Form):
197
197
 
198
198
  class SliderNumericForm(RangeNumericForm):
199
199
  class Media:
200
- css = {"all": ("unfold/filters/css/nouislider.min.css",)}
200
+ css = {"all": ("unfold/filters/css/nouislider/nouislider.min.css",)}
201
201
  js = (
202
- "unfold/filters/js/wNumb.min.js",
203
- "unfold/filters/js/nouislider.min.js",
202
+ "unfold/filters/js/wnumb/wNumb.min.js",
203
+ "unfold/filters/js/nouislider/nouislider.min.js",
204
204
  "unfold/filters/js/admin-numeric-filter.js",
205
205
  )
206
206
 
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Léon Gersen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Léon Gersen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Léon Gersen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -2,7 +2,7 @@
2
2
 
3
3
  {% with choices.0 as choice %}
4
4
  <div class="flex flex-col">
5
- <h3 class="font-semibold mb-2 text-font-important-light dark:text-font-important-dark">{% blocktrans with filter_title=title %}By {{ filter_title }}{% endblocktrans %}</h3>
5
+ <h3 class="font-semibold mb-2 text-font-important-light dark:text-font-important-dark">{% blocktranslate with filter_title=title %} By {{ filter_title }} {% endblocktranslate %}</h3>
6
6
 
7
7
  <div class="flex flex-col space-y-2">
8
8
  {% for field in choice.form %}
@@ -2,7 +2,7 @@
2
2
 
3
3
  {% with choices.0 as choice %}
4
4
  <div class="flex flex-col">
5
- <h3 class="font-semibold mb-2 text-font-important-light dark:text-font-important-dark">{% blocktrans with filter_title=title %}By {{ filter_title }}{% endblocktrans %}</h3>
5
+ <h3 class="font-semibold mb-2 text-font-important-light dark:text-font-important-dark">{% blocktranslate with filter_title=title %} By {{ filter_title }} {% endblocktranslate %}</h3>
6
6
 
7
7
  <div class="flex flex-col space-y-2">
8
8
  {% for field in choice.form %}
@@ -2,7 +2,7 @@
2
2
 
3
3
  {% with choices.0 as choice %}
4
4
  <div class="flex flex-col">
5
- <h3 class="font-semibold mb-2 text-font-important-light dark:text-font-important-dark">{% blocktrans with filter_title=title %}By {{ filter_title }}{% endblocktrans %}</h3>
5
+ <h3 class="font-semibold mb-2 text-font-important-light dark:text-font-important-dark">{% blocktranslate with filter_title=title %} By {{ filter_title }} {% endblocktranslate %}</h3>
6
6
 
7
7
  <div class="flex flex-row gap-4">
8
8
  {% for field in choice.form %}
@@ -2,7 +2,7 @@
2
2
 
3
3
  {% with choices.0 as choice %}
4
4
  <div class="flex flex-col">
5
- <h3 class="font-semibold mb-2 text-font-important-light dark:text-font-important-dark">{% blocktrans with filter_title=title %}By {{ filter_title }}{% endblocktrans %}</h3>
5
+ <h3 class="font-semibold mb-2 text-font-important-light dark:text-font-important-dark">{% blocktranslate with filter_title=title %} By {{ filter_title }} {% endblocktranslate %}</h3>
6
6
 
7
7
  {% for field in choice.form %}
8
8
  <div class="flex flex-row flex-wrap group relative{% if field.errors %} errors{% endif %}">
@@ -0,0 +1,20 @@
1
+ Copyright (c) 37signals, LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.