django-unfold 0.46.0__py3-none-any.whl → 0.47.0__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 (38) hide show
  1. {django_unfold-0.46.0.dist-info → django_unfold-0.47.0.dist-info}/METADATA +5 -6
  2. {django_unfold-0.46.0.dist-info → django_unfold-0.47.0.dist-info}/RECORD +38 -31
  3. {django_unfold-0.46.0.dist-info → django_unfold-0.47.0.dist-info}/WHEEL +1 -1
  4. unfold/admin.py +15 -16
  5. unfold/checks.py +4 -4
  6. unfold/components.py +5 -5
  7. unfold/contrib/filters/admin/__init__.py +43 -0
  8. unfold/contrib/filters/admin/autocomplete_filters.py +16 -0
  9. unfold/contrib/filters/admin/datetime_filters.py +212 -0
  10. unfold/contrib/filters/admin/dropdown_filters.py +100 -0
  11. unfold/contrib/filters/admin/mixins.py +146 -0
  12. unfold/contrib/filters/admin/numeric_filters.py +196 -0
  13. unfold/contrib/filters/admin/text_filters.py +65 -0
  14. unfold/contrib/filters/admin.py +32 -32
  15. unfold/contrib/filters/forms.py +68 -17
  16. unfold/contrib/forms/widgets.py +9 -9
  17. unfold/contrib/inlines/checks.py +2 -4
  18. unfold/contrib/simple_history/templates/simple_history/object_history.html +17 -1
  19. unfold/contrib/simple_history/templates/simple_history/object_history_list.html +1 -1
  20. unfold/dataclasses.py +2 -2
  21. unfold/decorators.py +4 -3
  22. unfold/settings.py +2 -2
  23. unfold/sites.py +156 -140
  24. unfold/static/unfold/css/styles.css +1 -1
  25. unfold/static/unfold/js/app.js +2 -2
  26. unfold/templates/admin/filter.html +1 -1
  27. unfold/templates/unfold/helpers/change_list_filter.html +2 -2
  28. unfold/templates/unfold/helpers/change_list_filter_actions.html +1 -1
  29. unfold/templates/unfold/helpers/header_back_button.html +2 -2
  30. unfold/templates/unfold/helpers/tab_list.html +7 -1
  31. unfold/templates/unfold/layouts/skeleton.html +1 -1
  32. unfold/templatetags/unfold.py +55 -22
  33. unfold/templatetags/unfold_list.py +2 -2
  34. unfold/typing.py +5 -4
  35. unfold/utils.py +3 -2
  36. unfold/views.py +2 -2
  37. unfold/widgets.py +27 -27
  38. {django_unfold-0.46.0.dist-info → django_unfold-0.47.0.dist-info}/LICENSE.md +0 -0
@@ -1,11 +1,10 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: django-unfold
3
- Version: 0.46.0
3
+ Version: 0.47.0
4
4
  Summary: Modern Django admin theme for seamless interface development
5
- Home-page: https://unfoldadmin.com
6
5
  License: MIT
7
6
  Keywords: django,admin,tailwind,theme
8
- Requires-Python: >=3.8
7
+ Requires-Python: >=3.9
9
8
  Classifier: Environment :: Web Environment
10
9
  Classifier: Framework :: Django
11
10
  Classifier: Intended Audience :: Developers
@@ -13,13 +12,13 @@ Classifier: License :: OSI Approved :: MIT License
13
12
  Classifier: Operating System :: OS Independent
14
13
  Classifier: Programming Language :: Python
15
14
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.8
17
15
  Classifier: Programming Language :: Python :: 3.9
18
16
  Classifier: Programming Language :: Python :: 3.10
19
17
  Classifier: Programming Language :: Python :: 3.11
20
18
  Classifier: Programming Language :: Python :: 3.12
21
19
  Classifier: Programming Language :: Python :: 3.13
22
20
  Requires-Dist: django (>=3.2)
21
+ Project-URL: Homepage, https://unfoldadmin.com
23
22
  Project-URL: Repository, https://github.com/unfoldadmin/django-unfold
24
23
  Description-Content-Type: text/markdown
25
24
 
@@ -52,7 +51,7 @@ Have you decided to start using Unfold but don’t have time to make the switch
52
51
  - **Sidebar:** Simplifies the creation of sidebar navigation with icons, collapsibles, and more.
53
52
  - **Dark mode:** Supports both light and dark mode versions.
54
53
  - **Actions:** Offers multiple ways to define actions within different parts of the admin interface.
55
- - **Filters:** Custom dropdowns, numeric, datetime, and text fields.
54
+ - **Filters:** Custom dropdowns, autocomplete, numeric, datetime, and text fields.
56
55
  - **Dashboard:** Includes helpers for creating custom dashboard pages.
57
56
  - **Components:** Reusable UI components such as cards, buttons, and charts.
58
57
  - **WYSIWYG widget:** Built-in support for WYSIWYG (Trix).
@@ -1,13 +1,20 @@
1
1
  unfold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- unfold/admin.py,sha256=mipNoMPKxrKv3dhzpWqWJgkE5U6Ve0O4EKQWBI6pvws,20060
2
+ unfold/admin.py,sha256=kIMEWKwiqnBo5eEDa_sBUlHh1XsZUhCt-Ct9bQ_H9vg,20018
3
3
  unfold/apps.py,sha256=SlBXPYrUd2uXn67qFbRvbXSUk3XFWrF4-5WELgDCvho,381
4
- unfold/checks.py,sha256=Smgji9w19hnYjJElJ_FJnnyTEAE-E-OUB6otHu7lasY,1670
5
- unfold/components.py,sha256=OKYEpAeawhqSUWOy0VB8EZTsPRzV19oOjSrWckLLeHI,1295
4
+ unfold/checks.py,sha256=8I3i4xR_KgyJdpQyZUZzKNeyYf-sNzg6PAlsREuMfgI,1664
5
+ unfold/components.py,sha256=vqkQzseYUvLXDohmTVAlbKopALjyX4WA9yglvdfhqu4,1283
6
6
  unfold/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  unfold/contrib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- unfold/contrib/filters/admin.py,sha256=L69oFj7DZMkLqJSJwY2bEh7VF_XqBEQ-uWYnWks1pME,21152
8
+ unfold/contrib/filters/admin/__init__.py,sha256=2pyv21jMqQVC8pnP8FOERHRH2hgZSOLQzV0BUn5wjHo,1216
9
+ unfold/contrib/filters/admin/autocomplete_filters.py,sha256=Jh3m3iQ8YubZRQDVzHPGfpk9RulOhHkZc0N7L6KV9wc,514
10
+ unfold/contrib/filters/admin/datetime_filters.py,sha256=cVari_7jsfeYxJoRBhcAUOr6v9XdtDtMuMs-S1Irafo,7757
11
+ unfold/contrib/filters/admin/dropdown_filters.py,sha256=SycJ6zgZbR4isy16oxiD0ZpAX_WuKUYNcifJG71b8Sw,3323
12
+ unfold/contrib/filters/admin/mixins.py,sha256=VMFyXz9yXGjOphB2pllKJSbJGnWkIpY33iq56OoG6Cg,4767
13
+ unfold/contrib/filters/admin/numeric_filters.py,sha256=8GNmesgMmMIfEZb2IrGbaBoJuvB2FpIc7wPIPBpHat4,6420
14
+ unfold/contrib/filters/admin/text_filters.py,sha256=NXyKm0Ed24N9pNfR7Dys5kTpZ_V5FUurdxk7KDMdRIg,2084
15
+ unfold/contrib/filters/admin.py,sha256=TvgtP5PZVMD9JJ22YdjC1CyH0Q9oxZON5zVXq2yGZVU,21127
9
16
  unfold/contrib/filters/apps.py,sha256=wEySJy0gMLzFLb9XNKE-RexiO05X7NaQ5QmxZyziJ_k,136
10
- unfold/contrib/filters/forms.py,sha256=p1vfCdhBVEGmvHG0EAtv12B1Ssm2xtXuImL4R0bHOV0,5748
17
+ unfold/contrib/filters/forms.py,sha256=lIhrmYv6rXXIT14xaChDpfzklUb-B9w8yz5YgdEegOg,7238
11
18
  unfold/contrib/filters/static/unfold/filters/css/nouislider.min.css,sha256=rddL_jOGGVEY6wR-aw0VYovAfz5fPeAIsulrlSNb1hc,4221
12
19
  unfold/contrib/filters/static/unfold/filters/js/DateTimeShortcuts.js,sha256=jgFNBDf6aHvUlyv0LEDHggXO-xA8pWOCWFWcVupdA30,19332
13
20
  unfold/contrib/filters/static/unfold/filters/js/admin-numeric-filter.js,sha256=nTkiiJk4Abn9d6KigxPSEsereFhFq-v5n_boiiY1eII,1668
@@ -27,7 +34,7 @@ unfold/contrib/forms/static/unfold/forms/js/trix.js,sha256=HJXkWw7Mtocr7IeyBVplE
27
34
  unfold/contrib/forms/templates/unfold/forms/array.html,sha256=utd_6pwpIDAP2WWg9uXofZzyuunk_u-x7EL7L-v5H-0,1779
28
35
  unfold/contrib/forms/templates/unfold/forms/helpers/toolbar.html,sha256=wK4yPTuKLmKdr_zonhksD3qONtbzchV19baIk6mqTXk,9746
29
36
  unfold/contrib/forms/templates/unfold/forms/wysiwyg.html,sha256=uLLf59jsD3apAm9Uh1TH4pwCOtO7pL2djAeZLOHyNAI,399
30
- unfold/contrib/forms/widgets.py,sha256=PuB1XnaKaL3ub-wbdpZAhvu9ZE79DBoAUG7FzyDFoiM,3139
37
+ unfold/contrib/forms/widgets.py,sha256=YiG6jRrVWMNW3NGAbqvm68FgcdTKyforROmhL7oAK9U,3127
31
38
  unfold/contrib/guardian/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
39
  unfold/contrib/guardian/apps.py,sha256=ObJqwh4vHxkD4XfduP5IQAiYiWZxsXUOUqF1_R1GsRI,136
33
40
  unfold/contrib/guardian/templates/admin/guardian/model/change_form.html,sha256=FSJc4MYYWyzZAy8Ay0b7Ov-cUo-oELHOM5fQehM54Lg,403
@@ -57,25 +64,25 @@ unfold/contrib/import_export/templates/admin/import_export/resource_fields_list.
57
64
  unfold/contrib/inlines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
65
  unfold/contrib/inlines/admin.py,sha256=LloGe9KaY0hb9LX0jICpWi01DcdnSCXRfpAdY9VxkiY,5929
59
66
  unfold/contrib/inlines/apps.py,sha256=Z9JBnzywq-DanZbD56fG0ndBfLXbojzkjVBleqoOBSU,136
60
- unfold/contrib/inlines/checks.py,sha256=8sdyBcxw0erqQvp9sHlpGgy0rXfum-cd2eQE0rXFKQ0,559
67
+ unfold/contrib/inlines/checks.py,sha256=0vkHUh-MtNSTrcOjCLbZmtI4961fFOygOv_dBAps6zw,534
61
68
  unfold/contrib/inlines/forms.py,sha256=s49xrIkQTbvSMsrP4DydXWkpP1v8NCUmQw_Bcoqf0i4,1322
62
69
  unfold/contrib/simple_history/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
70
  unfold/contrib/simple_history/apps.py,sha256=eF_KVYb60CAnGgWk2Z1YKYGfgA3TJBMr229qI7e2pgU,153
64
- unfold/contrib/simple_history/templates/simple_history/object_history.html,sha256=tlSA-y1742cCIIz7VHRBOvw0op9KT6gMhYVJWK0Tbdw,745
71
+ unfold/contrib/simple_history/templates/simple_history/object_history.html,sha256=z0yFKZB9iBX2aNanx-yBAD-ikshE1FCfbi2lTNDfIgA,1683
65
72
  unfold/contrib/simple_history/templates/simple_history/object_history_form.html,sha256=JKCe-QTBZMB2ol5LPiX3gNuNxFpi_rqlXC9X92PFBPE,2296
66
- unfold/contrib/simple_history/templates/simple_history/object_history_list.html,sha256=qp_D3gkKYaZPPfsgJrLa84hMdxFkEyI_pf4hynmi2zY,6852
73
+ unfold/contrib/simple_history/templates/simple_history/object_history_list.html,sha256=ls_xEAAgGzbu0IXdjZk7scEyEJx0S7i3Khr9ND98gzY,6842
67
74
  unfold/contrib/simple_history/templates/simple_history/submit_line.html,sha256=y8BleGHPNztA_R37rTB-zjJ68uDbE8flYSvMD0Jfl5Y,1734
68
- unfold/dataclasses.py,sha256=4PAWLVlUhyGMq1Mwai7afCgrRO0Inulw0opFUKVEOBk,483
69
- unfold/decorators.py,sha256=jyjE2sunazp8gK1QIsNRJGEEDwO7RDKWDKnOI3GDWZE,3338
75
+ unfold/dataclasses.py,sha256=KeFYN7m6AAUdtJKH0m7TGk8czU9pAt2MpWDAcdbSeR8,477
76
+ unfold/decorators.py,sha256=7VNVSz3KoaMwCRAcBGO18wURXozXWrf_B0qPQity46c,3359
70
77
  unfold/exceptions.py,sha256=gcCj1ox61E137bk_0Cqy4YC3SttdPgB-fiJUqpmyHSE,43
71
78
  unfold/fields.py,sha256=yhtpDfqycpOxqdQlbncCg9qhELxGk3AtXizkZyzzH0g,7410
72
79
  unfold/forms.py,sha256=BKv7eCbv29eCIuf1d_ZBmD4-_OIIzRaopiFd2nKbXNY,4520
73
- unfold/settings.py,sha256=5VqCrNcOdD_fe1z_O-Qt3LmXseeVSQEsUWrsmcBhrzc,2622
74
- unfold/sites.py,sha256=iXbwaDx5c_rFxXUrKIKeQxOFcCZ4-_nLBWCWIwNdC7U,15146
80
+ unfold/settings.py,sha256=Puhu2puoEuTImkEPjWv4J8OdnB_Az6iVrzQps1wWQKY,2616
81
+ unfold/sites.py,sha256=mO_BpbtkMs38AGOVOSLlo0eCasIg6YY9zg1gtnXIQKM,15287
75
82
  unfold/static/admin/js/admin/RelatedObjectLookups.js,sha256=alI0-yq7YPDJJJn-yg1ce79-Cv88yQDUrfaGqFZnsaY,9048
76
83
  unfold/static/admin/js/inlines.js,sha256=gxmQEUlJ9yasELjz9qpluogFZB-bD1KJfHs4PI7UjsA,14687
77
84
  unfold/static/unfold/css/simplebar.css,sha256=5LLaEM11pKi6JFCOLt4XKuZxTpT9rpdq_tNlaQytFlU,4647
78
- unfold/static/unfold/css/styles.css,sha256=uELyfb7w1gGpsd5HkhRGB3Hjt6Y-l3LC7Rb5UT7bYP8,157275
85
+ unfold/static/unfold/css/styles.css,sha256=qc7Zrl9JGiAylsSH8Nq6TqChuQ4aEuSnB7Ij1-J3rWQ,157285
79
86
  unfold/static/unfold/fonts/inter/Inter-Bold.woff2,sha256=O88EyjAeRPE_QEyKBKpK5wf2epUOEu8wwjj5bnhCZqE,46552
80
87
  unfold/static/unfold/fonts/inter/Inter-Medium.woff2,sha256=O88EyjAeRPE_QEyKBKpK5wf2epUOEu8wwjj5bnhCZqE,46552
81
88
  unfold/static/unfold/fonts/inter/Inter-Regular.woff2,sha256=O88EyjAeRPE_QEyKBKpK5wf2epUOEu8wwjj5bnhCZqE,46552
@@ -88,7 +95,7 @@ unfold/static/unfold/js/alpine.js,sha256=NY2a-7GrW--i9IBhowd25bzXcH9BCmBrqYX5i8O
88
95
  unfold/static/unfold/js/alpine.persist.js,sha256=jFBwr6faTqqhp3sVi4_VTxJ0FpaF9YGZN1ZGLl_5QYM,837
89
96
  unfold/static/unfold/js/alpine.resize.js,sha256=mXR2L6neT584cfNLY5_imDq5DKjW1noXys7fhb1yxY4,703
90
97
  unfold/static/unfold/js/alpine.sort.js,sha256=q6LxgConwu8M8R03mZSBcsKwJv6fF7oomP8sqLxVQ0w,37891
91
- unfold/static/unfold/js/app.js,sha256=dntPgbih0m4q2XCA3FmjQR5ypC6csekjwHp-3iA4aSY,7736
98
+ unfold/static/unfold/js/app.js,sha256=mxCSV8gZvRLHab-_Xm_229NtQ9IX-59vS_GKWTp9liM,7748
92
99
  unfold/static/unfold/js/chart.js,sha256=22W6cFERR-CElMOKRgMMicueMVP0Vf7FBEBYH8Z8tCk,200633
93
100
  unfold/static/unfold/js/htmx.js,sha256=acrv0NqSJpBm5yXX_hdeJrnVDJYuMFZFnAxHcVTNudM,50918
94
101
  unfold/static/unfold/js/select2.init.js,sha256=siSDCwzy2PsOwA0Kj26JA_ELBtZlS70O8D8f1qTMmqg,291
@@ -111,7 +118,7 @@ unfold/templates/admin/delete_confirmation.html,sha256=yT_NHbFHZEjkSCaGVcM52GCG-
111
118
  unfold/templates/admin/delete_selected_confirmation.html,sha256=QR0JhrPR8YI8KpQnB3xyrKxaui-_pEQmfaMDbcXjjZ0,4391
112
119
  unfold/templates/admin/edit_inline/stacked.html,sha256=-ASy7Jd0SwWBDxurucbus86YT2AokJEcCUrqPlHVDQA,7644
113
120
  unfold/templates/admin/edit_inline/tabular.html,sha256=FBgzUb-U0cZCN28-cpHzRSyPE6bgseD_r3MY1AP0nGQ,2813
114
- unfold/templates/admin/filter.html,sha256=ZXldjgLjrBVrNEtAc9H9zlMd_lXJBDhBk2yf2rMG1-Y,1965
121
+ unfold/templates/admin/filter.html,sha256=ZnnJbg-9e6LM0OyKJW7V-DA7mmxkGhJeOpEfnM5JGM8,1998
115
122
  unfold/templates/admin/includes/fieldset.html,sha256=gX-dc-jPLswk21XSKUXzAU8WFl3CFfeVrIAU2bviPyg,812
116
123
  unfold/templates/admin/includes/object_delete_summary.html,sha256=FgwfapZCKWtnFtTHqh1MRuxxLot4bAw92WCcR_V8ImI,444
117
124
  unfold/templates/admin/index.html,sha256=pkGdKWdD3zzOvkRdELvdb15sleSpfl4eHPA14PAh7z0,684
@@ -149,8 +156,8 @@ unfold/templates/unfold/helpers/attrs.html,sha256=Mwpj72kuwYj8hOT3J2T8qx6f1r_4xw
149
156
  unfold/templates/unfold/helpers/boolean.html,sha256=kcSZr3siQeBWIy_jsx1tFf4m6IB3ooRnu8UUNQrh6so,569
150
157
  unfold/templates/unfold/helpers/breadcrumb_item.html,sha256=9T6ojN7LOXIlgwSwlIwHgy5U22eQYtarCqcmzsQIoPU,201
151
158
  unfold/templates/unfold/helpers/change_list_actions.html,sha256=p1_vC2Q_Fb-gAHA8y1zzOXqqn5TPQMrQfE26PkOY_ok,656
152
- unfold/templates/unfold/helpers/change_list_filter.html,sha256=GlKdsLwnAcE8LS7FXQaV0tMWgCCgKdY6HX5IBhvmf7A,1876
153
- unfold/templates/unfold/helpers/change_list_filter_actions.html,sha256=nFiZltfPF0pT7s6eX87o7QNMC_NFG_RWaF9NlwxD9Fk,1742
159
+ unfold/templates/unfold/helpers/change_list_filter.html,sha256=0l-c4H2PcDkAuzI6asAJf2rBfYavYG62F9d7yWWdkSI,1852
160
+ unfold/templates/unfold/helpers/change_list_filter_actions.html,sha256=Dy8CGBPNuMJAHf1_ynGYOjLrsemQJI1vkDldKBWtSlk,1777
154
161
  unfold/templates/unfold/helpers/delete_submit_line.html,sha256=N1w_TDIDN7Spj5diuhRUVOVgz2TiSeHVK2QvBjTLv2w,665
155
162
  unfold/templates/unfold/helpers/display_header.html,sha256=rhru2GSxR0mH8_FEQuQVIS8gGGjaiWMV9f2HCPGMsaQ,1698
156
163
  unfold/templates/unfold/helpers/display_label.html,sha256=LS9DWzYjHkYLV27sZDwyXlg2sLJ0AlId9FbjnXpsbfg,317
@@ -170,7 +177,7 @@ unfold/templates/unfold/helpers/fieldsets_tabs.html,sha256=KW2rzVqpIICEu55GR_Knu
170
177
  unfold/templates/unfold/helpers/form_errors.html,sha256=EwerIJptSCWXvtAJ1IZKfEn98qlShBIGavsTThbklAs,266
171
178
  unfold/templates/unfold/helpers/form_label.html,sha256=BRX3DxVQfEvcmpFcRuhl4v_icMCCd5O_zmYm6MGLtts,327
172
179
  unfold/templates/unfold/helpers/header.html,sha256=ZoQH_Fs1v7fbo6fWQ5UEgfM9xPQlsYQxeabLf7nndB8,1050
173
- unfold/templates/unfold/helpers/header_back_button.html,sha256=0c8KPfVEl_ib0G_81TueVAq5fo4vtr3GCuinhTONw4g,371
180
+ unfold/templates/unfold/helpers/header_back_button.html,sha256=6DXkxsZJnIt0Z_AILDJNlj1gntEetFD-_b40mWFXwro,413
174
181
  unfold/templates/unfold/helpers/help_text.html,sha256=o-2_hyruIr_Xt0fo38aGgrpptPJFhddnVMPOVQOYhE4,113
175
182
  unfold/templates/unfold/helpers/history.html,sha256=QUYUQXcccyIl9pKPwVS_R8Is2Zo096rLZA6inlGNhkw,1921
176
183
  unfold/templates/unfold/helpers/label.html,sha256=pGzRBfuY8tos-imyA9psBxj7r93LUTfr78ff2rYPvmc,900
@@ -192,13 +199,13 @@ unfold/templates/unfold/helpers/site_icon.html,sha256=KYN0gI8U2Eoh2CFJxxYrwA0Oj6
192
199
  unfold/templates/unfold/helpers/site_logo.html,sha256=S_QJoT2qh0xw0ciaKxoT4GJ6QIH5eqgRSC0abbWWkOI,423
193
200
  unfold/templates/unfold/helpers/submit.html,sha256=4Mgf4lx7Atm8GPqD6LTJK3NA9zoSJjs9VPig7sDp8Ao,203
194
201
  unfold/templates/unfold/helpers/tab_action.html,sha256=l7TBZm5FjDjlJpTsYXFonLSFBDpN91jDiILY3hjjj5s,376
195
- unfold/templates/unfold/helpers/tab_list.html,sha256=FT_DMLyS0fBcV8LNJnwtGbkg0agDsLe0EmcawDfOxig,4509
202
+ unfold/templates/unfold/helpers/tab_list.html,sha256=ULuTZ7VaUFsgtqNr9eCb-A_Qmhp7gqt43V8sdu5fEII,5032
196
203
  unfold/templates/unfold/helpers/theme_switch.html,sha256=jiHqwz46GFb_pXjP23VTzV0S4E2LB-fdKpsIfjDaB8w,2201
197
204
  unfold/templates/unfold/helpers/userlinks.html,sha256=oZqiwCxG_zRecAbzYrr8_hQvkndVB6-liP6LEZM1UZc,863
198
205
  unfold/templates/unfold/helpers/welcomemsg.html,sha256=a7VjZ8J1mn-DAo57nhUP096SEcBOqcCWrWt2qoT0cyg,1882
199
206
  unfold/templates/unfold/layouts/base.html,sha256=bAXZDbyiyxNiE-49mqr7pHUFhC2mHZQzIDUY-js_yZ0,379
200
207
  unfold/templates/unfold/layouts/base_simple.html,sha256=VigjNWnWOt_XtbahvqsroPf8mdwl7cDGbg5fEaLmG9s,1211
201
- unfold/templates/unfold/layouts/skeleton.html,sha256=Z0N9FkqQRmBANMHg68-I_wupbywR3OThGzNMQGLwS3w,4540
208
+ unfold/templates/unfold/layouts/skeleton.html,sha256=cE29ydXMseyXut1k7Yme3alnUBFXhBDxT0WFZCgrvGQ,4600
202
209
  unfold/templates/unfold/templatetags/preserve_changelist_filters.html,sha256=sx2jUhogNY4emBhY8PqxQ6mXifbXQb_IQI9Hd0boJI0,111
203
210
  unfold/templates/unfold/widgets/clearable_file_input.html,sha256=4vsLRjqOmGqdU4aPSq81rc-mdRvpBr-H_bC5ScyUkEY,2231
204
211
  unfold/templates/unfold/widgets/clearable_file_input_small.html,sha256=NNlosUwhzv-3SZH9LdliL5c6fdoVNRb1JP0uHwFV-N8,2849
@@ -216,13 +223,13 @@ unfold/templates/unfold/widgets/textarea_expandable.html,sha256=Pqi2udY0FWxVA-B1
216
223
  unfold/templates/unfold/widgets/time.html,sha256=WXo2LG1v_gBZBSg-zocj7oujMKI0MWLYCIFfB04HMLQ,122
217
224
  unfold/templates/unfold/widgets/url.html,sha256=IRLgW44VTKN7UrSWeywJwaxQhfG5jhhXuT-KTadKX58,304
218
225
  unfold/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
219
- unfold/templatetags/unfold.py,sha256=l2OrOfU-m6sXvaGmSgQI3gvJoJ8PevGhK99YkrL8RxE,11181
220
- unfold/templatetags/unfold_list.py,sha256=QSDm69hqo3GpOMRe4O2uw7KpGirQCzXnpq23ZrZNyPw,14239
221
- unfold/typing.py,sha256=1P8PWM2oeaceUJtA5j071RbKEBpHYaux441u7Hd6wv4,643
222
- unfold/utils.py,sha256=36WgmgGRayf_fkNtjoFoI1_G9w8f8gZflNzzqQ3256U,5459
223
- unfold/views.py,sha256=hQCyeeMa9kcJV1IZeeYqj8PGW7J4QWME8n-5n0UGmiU,1003
224
- unfold/widgets.py,sha256=u3E_T4fBzP1_UL2gWuofX98mthINBRdQj3XWYuMjfmo,20185
225
- django_unfold-0.46.0.dist-info/LICENSE.md,sha256=Ltk_quRyyvV3J5v3brtOqmibeZSw2Hrb8bY1W3ya0Ik,1077
226
- django_unfold-0.46.0.dist-info/METADATA,sha256=7xSRpNo1C4BffSq61zmJJPm6GWlYxybumK3T1teTRFY,4864
227
- django_unfold-0.46.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
228
- django_unfold-0.46.0.dist-info/RECORD,,
226
+ unfold/templatetags/unfold.py,sha256=C2x_fqjVCWku4WdyaD_u4UjXq9eue1CgnmEz5PCfrS8,12364
227
+ unfold/templatetags/unfold_list.py,sha256=-KOU6Ib2k4gokuw_CgRooFCto8xJkiDyotbQbKAqkEY,14233
228
+ unfold/typing.py,sha256=ZVeXbABOYjUFgtGlFLMh6jdiM9bHVCwxMW0pNtbvwuw,651
229
+ unfold/utils.py,sha256=L0oC9-j1B__BZ21M7i6rTXNbzCQaZ4T0qHYQcNupk0A,5480
230
+ unfold/views.py,sha256=nqv-meiwGtCeET2r8WBVyijWnE94Dssc4QmdUVMMcEM,997
231
+ unfold/widgets.py,sha256=ZsjOAlQgEGmllPvXfN5ApbtW3VFs51lJzW4V44v9Ilg,20172
232
+ django_unfold-0.47.0.dist-info/LICENSE.md,sha256=Ltk_quRyyvV3J5v3brtOqmibeZSw2Hrb8bY1W3ya0Ik,1077
233
+ django_unfold-0.47.0.dist-info/METADATA,sha256=_tzSJ-F79LJ9a81ddDwS69HpaSi4cYWVWCMCnE1LHb0,4840
234
+ django_unfold-0.47.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
235
+ django_unfold-0.47.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.0
2
+ Generator: poetry-core 2.0.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
unfold/admin.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import copy
2
2
  from functools import update_wrapper
3
- from typing import Any, Callable, Dict, List, Optional, Tuple, Union
3
+ from typing import Any, Callable, Optional, Union
4
4
 
5
5
  from django import forms
6
6
  from django.contrib.admin import ModelAdmin as BaseModelAdmin
@@ -272,9 +272,9 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
272
272
  def _filter_unfold_actions_by_permissions(
273
273
  self,
274
274
  request: HttpRequest,
275
- actions: List[UnfoldAction],
275
+ actions: list[UnfoldAction],
276
276
  object_id: Optional[Union[int, str]] = None,
277
- ) -> List[UnfoldAction]:
277
+ ) -> list[UnfoldAction]:
278
278
  """Filter out any Unfold actions that the user doesn't have access to."""
279
279
  filtered_actions = []
280
280
  for action in actions:
@@ -299,12 +299,12 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
299
299
 
300
300
  return filtered_actions
301
301
 
302
- def get_actions_list(self, request: HttpRequest) -> List[UnfoldAction]:
302
+ def get_actions_list(self, request: HttpRequest) -> list[UnfoldAction]:
303
303
  return self._filter_unfold_actions_by_permissions(
304
304
  request, self._get_base_actions_list()
305
305
  )
306
306
 
307
- def _get_base_actions_list(self) -> List[UnfoldAction]:
307
+ def _get_base_actions_list(self) -> list[UnfoldAction]:
308
308
  """
309
309
  Returns all available list global actions, prior to any filtering
310
310
  """
@@ -312,23 +312,23 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
312
312
 
313
313
  def get_actions_detail(
314
314
  self, request: HttpRequest, object_id: int
315
- ) -> List[UnfoldAction]:
315
+ ) -> list[UnfoldAction]:
316
316
  return self._filter_unfold_actions_by_permissions(
317
317
  request, self._get_base_actions_detail(), object_id
318
318
  )
319
319
 
320
- def _get_base_actions_detail(self) -> List[UnfoldAction]:
320
+ def _get_base_actions_detail(self) -> list[UnfoldAction]:
321
321
  """
322
322
  Returns all available detail actions, prior to any filtering
323
323
  """
324
324
  return [self.get_unfold_action(action) for action in self.actions_detail or []]
325
325
 
326
- def get_actions_row(self, request: HttpRequest) -> List[UnfoldAction]:
326
+ def get_actions_row(self, request: HttpRequest) -> list[UnfoldAction]:
327
327
  return self._filter_unfold_actions_by_permissions(
328
328
  request, self._get_base_actions_row()
329
329
  )
330
330
 
331
- def _get_base_actions_row(self) -> List[UnfoldAction]:
331
+ def _get_base_actions_row(self) -> list[UnfoldAction]:
332
332
  """
333
333
  Returns all available row actions, prior to any filtering
334
334
  """
@@ -336,12 +336,12 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
336
336
 
337
337
  def get_actions_submit_line(
338
338
  self, request: HttpRequest, object_id: int
339
- ) -> List[UnfoldAction]:
339
+ ) -> list[UnfoldAction]:
340
340
  return self._filter_unfold_actions_by_permissions(
341
341
  request, self._get_base_actions_submit_line(), object_id
342
342
  )
343
343
 
344
- def _get_base_actions_submit_line(self) -> List[UnfoldAction]:
344
+ def _get_base_actions_submit_line(self) -> list[UnfoldAction]:
345
345
  """
346
346
  Returns all available submit row actions, prior to any filtering
347
347
  """
@@ -349,7 +349,7 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
349
349
  self.get_unfold_action(action) for action in self.actions_submit_line or []
350
350
  ]
351
351
 
352
- def get_custom_urls(self) -> Tuple[Tuple[str, str, View], ...]:
352
+ def get_custom_urls(self) -> tuple[tuple[str, str, View], ...]:
353
353
  """
354
354
  Method to get custom views for ModelAdmin with their urls
355
355
 
@@ -358,7 +358,7 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
358
358
  """
359
359
  return () if self.custom_urls is None else self.custom_urls
360
360
 
361
- def get_urls(self) -> List[URLPattern]:
361
+ def get_urls(self) -> list[URLPattern]:
362
362
  urls = super().get_urls()
363
363
 
364
364
  def wrap(view):
@@ -409,7 +409,6 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
409
409
  )
410
410
 
411
411
  def _path_from_custom_url(self, custom_url) -> URLPattern:
412
- # TODO: wrap()
413
412
  return path(
414
413
  custom_url[0],
415
414
  self.admin_site.admin_view(custom_url[2]),
@@ -422,7 +421,7 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
422
421
  request: HttpRequest,
423
422
  object_id: Optional[str] = None,
424
423
  form_url: str = "",
425
- extra_context: Optional[Dict[str, bool]] = None,
424
+ extra_context: Optional[dict[str, bool]] = None,
426
425
  ) -> Any:
427
426
  if extra_context is None:
428
427
  extra_context = {}
@@ -451,7 +450,7 @@ class ModelAdmin(ModelAdminMixin, BaseModelAdmin):
451
450
  return super().changeform_view(request, object_id, form_url, extra_context)
452
451
 
453
452
  def changelist_view(
454
- self, request: HttpRequest, extra_context: Optional[Dict[str, str]] = None
453
+ self, request: HttpRequest, extra_context: Optional[dict[str, str]] = None
455
454
  ) -> TemplateResponse:
456
455
  if extra_context is None:
457
456
  extra_context = {}
unfold/checks.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Any, List
1
+ from typing import Any
2
2
 
3
3
  from django.contrib.admin.checks import ModelAdminChecks
4
4
  from django.contrib.admin.options import BaseModelAdmin
@@ -8,18 +8,18 @@ from .dataclasses import UnfoldAction
8
8
 
9
9
 
10
10
  class UnfoldModelAdminChecks(ModelAdminChecks):
11
- def check(self, admin_obj: BaseModelAdmin, **kwargs) -> List[checks.Error]:
11
+ def check(self, admin_obj: BaseModelAdmin, **kwargs) -> list[checks.Error]:
12
12
  return [
13
13
  *super().check(admin_obj, **kwargs),
14
14
  *self._check_unfold_action_permission_methods(admin_obj),
15
15
  ]
16
16
 
17
- def _check_unfold_action_permission_methods(self, obj: Any) -> List[checks.Error]:
17
+ def _check_unfold_action_permission_methods(self, obj: Any) -> list[checks.Error]:
18
18
  """
19
19
  Actions with an allowed_permission attribute require the ModelAdmin to
20
20
  implement a has_<perm>_permission() method for each permission.
21
21
  """
22
- actions: List[UnfoldAction] = [
22
+ actions: list[UnfoldAction] = [
23
23
  *obj._get_base_actions_list(),
24
24
  *obj._get_base_actions_detail(),
25
25
  *obj._get_base_actions_row(),
unfold/components.py CHANGED
@@ -1,13 +1,13 @@
1
- from typing import Any, Dict, Optional, Type
1
+ from typing import Any, Optional
2
2
 
3
3
  from django.http import HttpRequest
4
4
 
5
5
 
6
6
  class ComponentRegistry:
7
- _registry: Dict[str, Type] = {}
7
+ _registry: dict[str, type] = {}
8
8
 
9
9
  @classmethod
10
- def register_class(cls, component_cls: Type) -> None:
10
+ def register_class(cls, component_cls: type) -> None:
11
11
  if not issubclass(component_cls, BaseComponent):
12
12
  raise ValueError(
13
13
  f"Class '{component_cls.__name__}' must inherit from BaseComponent."
@@ -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) -> Optional[type]:
25
25
  return cls._registry.get(class_name)
26
26
 
27
27
  @classmethod
@@ -34,7 +34,7 @@ class ComponentRegistry:
34
34
  return component_cls(**kwargs)
35
35
 
36
36
 
37
- def register_component(cls: Type) -> Type:
37
+ def register_component(cls: type) -> type:
38
38
  ComponentRegistry.register_class(cls)
39
39
  return cls
40
40
 
@@ -0,0 +1,43 @@
1
+ from unfold.contrib.filters.admin.autocomplete_filters import (
2
+ AutocompleteSelectFilter,
3
+ AutocompleteSelectMultipleFilter,
4
+ )
5
+ from unfold.contrib.filters.admin.datetime_filters import (
6
+ RangeDateFilter,
7
+ RangeDateTimeFilter,
8
+ )
9
+ from unfold.contrib.filters.admin.dropdown_filters import (
10
+ ChoicesDropdownFilter,
11
+ DropdownFilter,
12
+ MultipleChoicesDropdownFilter,
13
+ MultipleDropdownFilter,
14
+ MultipleRelatedDropdownFilter,
15
+ RelatedDropdownFilter,
16
+ )
17
+ from unfold.contrib.filters.admin.numeric_filters import (
18
+ RangeNumericFilter,
19
+ RangeNumericListFilter,
20
+ SingleNumericFilter,
21
+ SliderNumericFilter,
22
+ )
23
+ from unfold.contrib.filters.admin.text_filters import FieldTextFilter, TextFilter
24
+
25
+ __all__ = [
26
+ "ChoicesDropdownFilter",
27
+ "MultipleChoicesDropdownFilter",
28
+ "DropdownFilter",
29
+ "RelatedDropdownFilter",
30
+ "MultipleDropdownFilter",
31
+ "MultipleRelatedDropdownFilter",
32
+ "FieldTextFilter",
33
+ "TextFilter",
34
+ "RangeDateFilter",
35
+ "RangeDateFilter",
36
+ "RangeDateTimeFilter",
37
+ "SingleNumericFilter",
38
+ "RangeNumericFilter",
39
+ "RangeNumericListFilter",
40
+ "SliderNumericFilter",
41
+ "AutocompleteSelectFilter",
42
+ "AutocompleteSelectMultipleFilter",
43
+ ]
@@ -0,0 +1,16 @@
1
+ from unfold.contrib.filters.admin.dropdown_filters import (
2
+ MultipleRelatedDropdownFilter,
3
+ RelatedDropdownFilter,
4
+ )
5
+ from unfold.contrib.filters.admin.mixins import AutocompleteMixin
6
+ from unfold.contrib.filters.forms import AutocompleteDropdownForm
7
+
8
+
9
+ class AutocompleteSelectFilter(AutocompleteMixin, RelatedDropdownFilter):
10
+ form_class = AutocompleteDropdownForm
11
+
12
+
13
+ class AutocompleteSelectMultipleFilter(
14
+ AutocompleteMixin, MultipleRelatedDropdownFilter
15
+ ):
16
+ form_class = AutocompleteDropdownForm
@@ -0,0 +1,212 @@
1
+ from typing import Any
2
+
3
+ from django.contrib import admin
4
+ from django.contrib.admin.options import ModelAdmin
5
+ from django.contrib.admin.views.main import ChangeList
6
+ from django.core.validators import EMPTY_VALUES
7
+ from django.db.models import Model, QuerySet
8
+ from django.db.models.fields import (
9
+ DateField,
10
+ DateTimeField,
11
+ Field,
12
+ )
13
+ from django.forms import ValidationError
14
+ from django.http import HttpRequest
15
+
16
+ from unfold.contrib.filters.forms import (
17
+ RangeDateForm,
18
+ RangeDateTimeForm,
19
+ )
20
+ from unfold.utils import parse_date_str, parse_datetime_str
21
+
22
+
23
+ class RangeDateFilter(admin.FieldListFilter):
24
+ request = None
25
+ parameter_name = None
26
+ form_class = RangeDateForm
27
+ template = "unfold/filters/filters_date_range.html"
28
+
29
+ def __init__(
30
+ self,
31
+ field: Field,
32
+ request: HttpRequest,
33
+ params: dict[str, str],
34
+ model: type[Model],
35
+ model_admin: ModelAdmin,
36
+ field_path: str,
37
+ ) -> None:
38
+ super().__init__(field, request, params, model, model_admin, field_path)
39
+ if not isinstance(field, DateField):
40
+ raise TypeError(
41
+ f"Class {type(self.field)} is not supported for {self.__class__.__name__}."
42
+ )
43
+
44
+ self.request = request
45
+ if self.parameter_name is None:
46
+ self.parameter_name = self.field_path
47
+
48
+ if self.parameter_name + "_from" in params:
49
+ value = params.pop(self.field_path + "_from")
50
+ value = value[0] if isinstance(value, list) else value
51
+
52
+ if value not in EMPTY_VALUES:
53
+ self.used_parameters[self.field_path + "_from"] = value
54
+
55
+ if self.parameter_name + "_to" in params:
56
+ value = params.pop(self.field_path + "_to")
57
+ value = value[0] if isinstance(value, list) else value
58
+
59
+ if value not in EMPTY_VALUES:
60
+ self.used_parameters[self.field_path + "_to"] = value
61
+
62
+ def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet:
63
+ filters = {}
64
+
65
+ value_from = self.used_parameters.get(self.parameter_name + "_from")
66
+ if value_from not in EMPTY_VALUES:
67
+ filters.update({self.parameter_name + "__gte": parse_date_str(value_from)})
68
+
69
+ value_to = self.used_parameters.get(self.parameter_name + "_to")
70
+ if value_to not in EMPTY_VALUES:
71
+ filters.update({self.parameter_name + "__lte": parse_date_str(value_to)})
72
+
73
+ try:
74
+ return queryset.filter(**filters)
75
+ except (ValueError, ValidationError):
76
+ return None
77
+
78
+ def expected_parameters(self) -> list[str]:
79
+ return [
80
+ f"{self.parameter_name}_from",
81
+ f"{self.parameter_name}_to",
82
+ ]
83
+
84
+ def choices(self, changelist: ChangeList) -> tuple[dict[str, Any], ...]:
85
+ return (
86
+ {
87
+ "request": self.request,
88
+ "parameter_name": self.parameter_name,
89
+ "form": self.form_class(
90
+ name=self.parameter_name,
91
+ data={
92
+ self.parameter_name + "_from": self.used_parameters.get(
93
+ self.parameter_name + "_from", None
94
+ ),
95
+ self.parameter_name + "_to": self.used_parameters.get(
96
+ self.parameter_name + "_to", None
97
+ ),
98
+ },
99
+ ),
100
+ },
101
+ )
102
+
103
+
104
+ class RangeDateTimeFilter(admin.FieldListFilter):
105
+ request = None
106
+ parameter_name = None
107
+ template = "unfold/filters/filters_datetime_range.html"
108
+ form_class = RangeDateTimeForm
109
+
110
+ def __init__(
111
+ self,
112
+ field: Field,
113
+ request: HttpRequest,
114
+ params: dict[str, str],
115
+ model: type[Model],
116
+ model_admin: ModelAdmin,
117
+ field_path: str,
118
+ ) -> None:
119
+ super().__init__(field, request, params, model, model_admin, field_path)
120
+ if not isinstance(field, DateTimeField):
121
+ raise TypeError(
122
+ f"Class {type(self.field)} is not supported for {self.__class__.__name__}."
123
+ )
124
+
125
+ self.request = request
126
+ if self.parameter_name is None:
127
+ self.parameter_name = self.field_path
128
+
129
+ if self.parameter_name + "_from_0" in params:
130
+ value = params.pop(self.field_path + "_from_0")
131
+ value = value[0] if isinstance(value, list) else value
132
+ self.used_parameters[self.field_path + "_from_0"] = value
133
+
134
+ if self.parameter_name + "_from_1" in params:
135
+ value = params.pop(self.field_path + "_from_1")
136
+ value = value[0] if isinstance(value, list) else value
137
+ self.used_parameters[self.field_path + "_from_1"] = value
138
+
139
+ if self.parameter_name + "_to_0" in params:
140
+ value = params.pop(self.field_path + "_to_0")
141
+ value = value[0] if isinstance(value, list) else value
142
+ self.used_parameters[self.field_path + "_to_0"] = value
143
+
144
+ if self.parameter_name + "_to_1" in params:
145
+ value = params.pop(self.field_path + "_to_1")
146
+ value = value[0] if isinstance(value, list) else value
147
+ self.used_parameters[self.field_path + "_to_1"] = value
148
+
149
+ def expected_parameters(self) -> list[str]:
150
+ return [
151
+ f"{self.parameter_name}_from_0",
152
+ f"{self.parameter_name}_from_1",
153
+ f"{self.parameter_name}_to_0",
154
+ f"{self.parameter_name}_to_1",
155
+ ]
156
+
157
+ def queryset(self, request: HttpRequest, queryset: QuerySet) -> QuerySet:
158
+ filters = {}
159
+
160
+ date_value_from = self.used_parameters.get(self.parameter_name + "_from_0")
161
+ time_value_from = self.used_parameters.get(self.parameter_name + "_from_1")
162
+
163
+ date_value_to = self.used_parameters.get(self.parameter_name + "_to_0")
164
+ time_value_to = self.used_parameters.get(self.parameter_name + "_to_1")
165
+
166
+ if date_value_from not in EMPTY_VALUES and time_value_from not in EMPTY_VALUES:
167
+ filters.update(
168
+ {
169
+ f"{self.parameter_name}__gte": parse_datetime_str(
170
+ f"{date_value_from} {time_value_from}"
171
+ ),
172
+ }
173
+ )
174
+
175
+ if date_value_to not in EMPTY_VALUES and time_value_to not in EMPTY_VALUES:
176
+ filters.update(
177
+ {
178
+ f"{self.parameter_name}__lte": parse_datetime_str(
179
+ f"{date_value_to} {time_value_to}"
180
+ ),
181
+ }
182
+ )
183
+
184
+ try:
185
+ return queryset.filter(**filters)
186
+ except (ValueError, ValidationError):
187
+ return None
188
+
189
+ def choices(self, changelist: ChangeList) -> tuple[dict[str, Any], ...]:
190
+ return (
191
+ {
192
+ "request": self.request,
193
+ "parameter_name": self.parameter_name,
194
+ "form": self.form_class(
195
+ name=self.parameter_name,
196
+ data={
197
+ self.parameter_name + "_from_0": self.used_parameters.get(
198
+ self.parameter_name + "_from_0"
199
+ ),
200
+ self.parameter_name + "_from_1": self.used_parameters.get(
201
+ self.parameter_name + "_from_1"
202
+ ),
203
+ self.parameter_name + "_to_0": self.used_parameters.get(
204
+ self.parameter_name + "_to_0"
205
+ ),
206
+ self.parameter_name + "_to_1": self.used_parameters.get(
207
+ self.parameter_name + "_to_1"
208
+ ),
209
+ },
210
+ ),
211
+ },
212
+ )