django-unfold 0.59.0__py3-none-any.whl → 0.60.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 (33) hide show
  1. {django_unfold-0.59.0.dist-info → django_unfold-0.60.0.dist-info}/METADATA +3 -2
  2. {django_unfold-0.59.0.dist-info → django_unfold-0.60.0.dist-info}/RECORD +33 -25
  3. unfold/admin.py +45 -13
  4. unfold/contrib/inlines/admin.py +11 -6
  5. unfold/contrib/inlines/forms.py +3 -1
  6. unfold/contrib/location_field/__init__.py +0 -0
  7. unfold/contrib/location_field/apps.py +6 -0
  8. unfold/contrib/location_field/templates/location_field/map_widget.html +5 -0
  9. unfold/fields.py +17 -19
  10. unfold/forms.py +95 -1
  11. unfold/mixins/base_model_admin.py +15 -1
  12. unfold/sites.py +3 -29
  13. unfold/static/admin/js/admin/RelatedObjectLookups.js +2 -2
  14. unfold/static/unfold/css/styles.css +1 -1
  15. unfold/styles.css +3 -3
  16. unfold/templates/admin/app_list.html +4 -1
  17. unfold/templates/admin/edit_inline/stacked.html +12 -8
  18. unfold/templates/admin/edit_inline/tabular.html +2 -0
  19. unfold/templates/admin/includes/fieldset.html +1 -1
  20. unfold/templates/admin/login.html +45 -88
  21. unfold/templates/unfold/components/button.html +10 -1
  22. unfold/templates/unfold/helpers/app_list.html +5 -2
  23. unfold/templates/unfold/helpers/app_list_default.html +2 -1
  24. unfold/templates/unfold/helpers/field.html +5 -3
  25. unfold/templates/unfold/helpers/pagination_inline.html +28 -0
  26. unfold/templates/unfold/helpers/unauthenticated_header.html +15 -0
  27. unfold/templates/unfold/helpers/unauthenticated_title.html +11 -0
  28. unfold/templates/unfold/layouts/unauthenticated.html +37 -0
  29. unfold/templates/unfold/widgets/text.html +28 -0
  30. unfold/templatetags/unfold.py +31 -1
  31. unfold/widgets.py +41 -1
  32. {django_unfold-0.59.0.dist-info → django_unfold-0.60.0.dist-info}/LICENSE.md +0 -0
  33. {django_unfold-0.59.0.dist-info → django_unfold-0.60.0.dist-info}/WHEEL +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-unfold
3
- Version: 0.59.0
3
+ Version: 0.60.0
4
4
  Summary: Modern Django admin theme for seamless interface development
5
5
  License: MIT
6
6
  Keywords: django,admin,tailwind,theme
@@ -50,11 +50,11 @@ Unfold Studio is a theme customizer for Django admin that helps you create a bra
50
50
 
51
51
  ## Fresh Features & Enhancements
52
52
 
53
+ - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
53
54
  - **Conditional fields:** Show or hide fields dynamically based on the values of other fields in the form
54
55
  - **Infinite paginator:** Efficiently handle large datasets with seamless pagination that reduces server load
55
56
  - **Checkbox & radio filters:** Enhanced filter options with checkbox and radio interfaces for intuitive filtering
56
57
  - **Site dropdown:** Configurable dropdown menu in the header area for managing custom navigation links
57
- - **Dropdown actions:** Organize action items in customizable dropdown menus
58
58
 
59
59
  ## Core Features & Capabilities
60
60
 
@@ -74,6 +74,7 @@ Unfold Studio is a theme customizer for Django admin that helps you create a bra
74
74
  - **Sortable inlines:** Allow sorting inlines by dragging and dropping
75
75
  - **Environment label:** Distinguish between environments by displaying a label
76
76
  - **Nonrelated inlines:** Display nonrelated models as inlines in the change form
77
+ - **Paginated inlines:** Break down large record sets into pages within inlines for better admin performance
77
78
  - **Favicons:** Built-in support for configuring various site favicons
78
79
  - **Themes:** Allow customization of color scheme, background color, border radius, and more
79
80
  - **Font colors:** Adjust font colors for better readability
@@ -1,5 +1,5 @@
1
1
  unfold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- unfold/admin.py,sha256=2YwKqP5slOtqpEInq_u-0-XlddY7Qnj21VeH-lsLkxg,6552
2
+ unfold/admin.py,sha256=GKntMIZnksjuAuHZQ9ppw6NlKPU_59V-EC-gEaZa61I,7451
3
3
  unfold/apps.py,sha256=SlBXPYrUd2uXn67qFbRvbXSUk3XFWrF4-5WELgDCvho,381
4
4
  unfold/checks.py,sha256=e5HEhbXRcu3FwZDT_d-IbimeVpjJ6jgCUPXWvsUjEw0,2601
5
5
  unfold/components.py,sha256=vqkQzseYUvLXDohmTVAlbKopALjyX4WA9yglvdfhqu4,1283
@@ -67,10 +67,13 @@ unfold/contrib/import_export/templates/admin/import_export/import_preview.html,s
67
67
  unfold/contrib/import_export/templates/admin/import_export/import_validation.html,sha256=K7j5OlWMQUTcSVulJtIraKfWIupSvmN4R5bZ2hH4tRA,5117
68
68
  unfold/contrib/import_export/templates/admin/import_export/resource_fields_list.html,sha256=Bc6uD8aHA5YYbZgLAPpGUckFjnxn9uq19YuKKFxTj4Y,887
69
69
  unfold/contrib/inlines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- unfold/contrib/inlines/admin.py,sha256=LloGe9KaY0hb9LX0jICpWi01DcdnSCXRfpAdY9VxkiY,5929
70
+ unfold/contrib/inlines/admin.py,sha256=__U86gR2OfdEiLPmOsKwTu7t8X2be8_jL-NL1SSNb3Q,6066
71
71
  unfold/contrib/inlines/apps.py,sha256=Z9JBnzywq-DanZbD56fG0ndBfLXbojzkjVBleqoOBSU,136
72
72
  unfold/contrib/inlines/checks.py,sha256=0vkHUh-MtNSTrcOjCLbZmtI4961fFOygOv_dBAps6zw,534
73
- unfold/contrib/inlines/forms.py,sha256=s49xrIkQTbvSMsrP4DydXWkpP1v8NCUmQw_Bcoqf0i4,1322
73
+ unfold/contrib/inlines/forms.py,sha256=noZdrBgvsu9tCBbRW3f9p7o6xKSuXtWR14qbZPdZBPA,1395
74
+ unfold/contrib/location_field/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
+ unfold/contrib/location_field/apps.py,sha256=qbNLfWXWf9q_gZxnuwFNVj20liSk_OT29uWMAi1she8,150
76
+ unfold/contrib/location_field/templates/location_field/map_widget.html,sha256=HXNqZ7TRh8zxq7jxGv5V5De7jdB_L6smXSWX_KXujJs,179
74
77
  unfold/contrib/simple_history/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
78
  unfold/contrib/simple_history/apps.py,sha256=eF_KVYb60CAnGgWk2Z1YKYGfgA3TJBMr229qI7e2pgU,153
76
79
  unfold/contrib/simple_history/templates/simple_history/object_history.html,sha256=unZQE70be7cK6v0YPlITFeaosmiLt3kiei-pmmCjBg0,1711
@@ -81,22 +84,22 @@ unfold/dataclasses.py,sha256=a-9INnkCAIcnMgoffTcB1rxWCJH33AjhMCWIGWnjWbI,719
81
84
  unfold/decorators.py,sha256=jPiYFy1p0WGFn68VZhAZkYCPDF7argb9SDFaH6aemHk,4922
82
85
  unfold/enums.py,sha256=9sTfyEycMWeoGPBa-ft6ZhQGnW1vkFg108RMBVf9nko,187
83
86
  unfold/exceptions.py,sha256=gcCj1ox61E137bk_0Cqy4YC3SttdPgB-fiJUqpmyHSE,43
84
- unfold/fields.py,sha256=g8gWFWsCQAooTBT8ngASaryW3fgaBZx6aPuTdLc1NqY,7472
85
- unfold/forms.py,sha256=f8OanxLAmV6dftNj-apgjtCrIVj_iEU830AbMeZh71I,4709
87
+ unfold/fields.py,sha256=h7mpRlsoFu6xQrCbehrjsBpyxFsXc-lMDzEI1JREoJk,7304
88
+ unfold/forms.py,sha256=N2VN_rhy-U0XXae1TWIZam-fJimR8YXJGm-pt_G2zp4,7747
86
89
  unfold/layout.py,sha256=Q-dFTA6UlvvPCA4PsGyTkHQmBLO7PL56xBfZi-bdt0c,1459
87
90
  unfold/mixins/__init__.py,sha256=YlhoDs9Y_DXQ8Ejr3enxuHMS1-Ij9fwukxNwpeOS4Co,190
88
91
  unfold/mixins/action_model_admin.py,sha256=9Zt4FLrQWEQSO2vrpwjzpFo_I3_yE000uEwHndsW5kg,12365
89
- unfold/mixins/base_model_admin.py,sha256=PR4eqU48yB4CNy9Bjd7fjxbOFiFpZM4etYmBOSaRX_M,4140
92
+ unfold/mixins/base_model_admin.py,sha256=dGxyd2ATcfMdzUlBuNOr059kbuFVLWXL8_VpHV8nV84,4611
90
93
  unfold/overrides.py,sha256=ERVY9boZiXgjDYcTEZcIp7KWoeBZ45VM_zN31yAOjyQ,2922
91
94
  unfold/paginator.py,sha256=bZiEY-1kqZy_6CYGs9fHo6WntMgpnFCH-LJPoXkEESk,533
92
95
  unfold/sections.py,sha256=Lcg3xCZ76fqjm4vD4x7YdE5VsbTKluL-sX5QTEBlHxA,2379
93
96
  unfold/settings.py,sha256=DE3hComMaWtty8o-LqdgGGcoku3mevRWJah4NH1k5B4,2879
94
- unfold/sites.py,sha256=Zxz2ey_rfFnCrYwqiPaLAvUDSehftPxFLOm-AX6b50M,18166
95
- unfold/static/admin/js/admin/RelatedObjectLookups.js,sha256=0bZ2MGuO6F0IF_lQ7-hTP6ofqZtrH44Pt4ElaPqyNz8,9199
97
+ unfold/sites.py,sha256=QY6PVMAM6CPxFytcoJP3lj40WaorSJSjSHAoHnQbg-k,17291
98
+ unfold/static/admin/js/admin/RelatedObjectLookups.js,sha256=ubKKhWmX_QborwPnaLHuQshTwQw6tK1pAViWdKIjw4E,9222
96
99
  unfold/static/admin/js/inlines.js,sha256=zcYwLGI_6RHg-gucDbbhp43RRoZd3so8bPk841KFaIE,15573
97
100
  unfold/static/unfold/css/simplebar/LICENSE,sha256=okNJf6UFl2NrEiC4iqORNBa16IKgUgV88acdcl9FbtY,1081
98
101
  unfold/static/unfold/css/simplebar/simplebar.css,sha256=5LLaEM11pKi6JFCOLt4XKuZxTpT9rpdq_tNlaQytFlU,4647
99
- unfold/static/unfold/css/styles.css,sha256=RYbHZGbPj3wTqi87UahjSTRRTeoC1Jrfpjah-o612jU,159143
102
+ unfold/static/unfold/css/styles.css,sha256=LqAcA9FY50-oBxSdJIf0jAWaIPW70Z4qsMgGhredRB0,158705
100
103
  unfold/static/unfold/fonts/inter/Inter-Bold.woff2,sha256=-oiBJ7baAVtlVp8DUfO1w5GtkokElR8cIOn4RiqNleo,114840
101
104
  unfold/static/unfold/fonts/inter/Inter-Medium.woff2,sha256=D_PpRhThST61VjFP0keubEqFp3g7TMhr5TmUDPg_Kkg,114348
102
105
  unfold/static/unfold/fonts/inter/Inter-Regular.woff2,sha256=4G9rG8VTqupORmgCPtCrChRxKcMQf1Ebx9A9NhsK4IU,111268
@@ -120,10 +123,10 @@ unfold/static/unfold/js/htmx/htmx.js,sha256=acrv0NqSJpBm5yXX_hdeJrnVDJYuMFZFnAxH
120
123
  unfold/static/unfold/js/select2.init.js,sha256=l0O8ggw_CkAw-QtH3qEzC8xWk0mR9QHjy4VzAjMwiQQ,1109
121
124
  unfold/static/unfold/js/simplebar/LICENSE,sha256=okNJf6UFl2NrEiC4iqORNBa16IKgUgV88acdcl9FbtY,1081
122
125
  unfold/static/unfold/js/simplebar/simplebar.js,sha256=t-uG1FAD6ZoiMeN--wac0XRS7SxoDVG6zvRnGuEp7X8,27176
123
- unfold/styles.css,sha256=YSDKjgENtZyAg9ceUztuJj9JXgAlUr3wJpwnSOZ6TMc,21246
126
+ unfold/styles.css,sha256=nHXgzszvYC6doRZQf3UlZTVcyPsNgb5rSibZVqAxmd4,21208
124
127
  unfold/templates/admin/actions.html,sha256=iuuubcAILkOoYBgV6cpXqFIyZUh4zMqyFp0JaDFlPKU,3096
125
128
  unfold/templates/admin/app_index.html,sha256=LRR07CLcZVsYpisCOncWdMSACARNstcDt536Oydnt60,1239
126
- unfold/templates/admin/app_list.html,sha256=2JbGENeKAVqYGYwm2Yv7I0lzQrLz0xRND18kPiMIi_Q,2861
129
+ unfold/templates/admin/app_list.html,sha256=-DEZKFdmkdTq3rix_cgZurPZ1r8PHg5pBL3i7ZtzVdI,2972
127
130
  unfold/templates/admin/auth/user/add_form.html,sha256=tZgg6UoKxJ7zL6T99PLHlLBwd4LlDI2mGn6d5hmtsPs,486
128
131
  unfold/templates/admin/auth/user/change_password.html,sha256=028v1dfQTlSmdr-WCuV4lBOmFa7Oo38CsYhsXEe8ANI,2831
129
132
  unfold/templates/admin/base.html,sha256=z9sU8rezHLqOZk5x13_5nvnqpRYf6XxQaMfa7N_GU68,2460
@@ -136,13 +139,13 @@ unfold/templates/admin/change_list_results.html,sha256=u9eUoOTWJ9woVeLVYhftAriCX
136
139
  unfold/templates/admin/date_hierarchy.html,sha256=A-sIqBKzZTMqSn3NSHORIL1yTEAqhj4Atff0OvWtqT0,1413
137
140
  unfold/templates/admin/delete_confirmation.html,sha256=IPSGhOpxDl6hJB9LtpSg_XRkVmbDO1BpO9q_dthqkac,4635
138
141
  unfold/templates/admin/delete_selected_confirmation.html,sha256=T3NNe7pP0WM2QM4F39AbkDGsfd_d_tKYRpwxvExahgU,4399
139
- unfold/templates/admin/edit_inline/stacked.html,sha256=RvdjkyXnTEzpWAI0GidvqxEFFK4x8NCEVHMlE2Y6OLQ,7664
140
- unfold/templates/admin/edit_inline/tabular.html,sha256=F8o80H3GVHcGv_OARw0l5XrMPKXcgdNWX4cgorsNvkU,2948
142
+ unfold/templates/admin/edit_inline/stacked.html,sha256=MNIFkU5YI2Olwu4jNlQ-qnPTiNms4MM2j9UlYFdU108,8232
143
+ unfold/templates/admin/edit_inline/tabular.html,sha256=v-4YjGqHLMT40tv_aMua5lK5z6T19bejFvETdMK5u94,3011
141
144
  unfold/templates/admin/filter.html,sha256=DEyrLgCWuncS1O1WR0vlt1evGQFvKoZV2pABkHzSoGU,2039
142
- unfold/templates/admin/includes/fieldset.html,sha256=F1XS_7bxeIbIxILjNdclXk_jFTmceUs_fZ4GjVwT1VM,1161
145
+ unfold/templates/admin/includes/fieldset.html,sha256=QjEx8UBivPdibePGkg30xGYUS6Smcu2wIeDTHsaM0PM,1132
143
146
  unfold/templates/admin/includes/object_delete_summary.html,sha256=FgwfapZCKWtnFtTHqh1MRuxxLot4bAw92WCcR_V8ImI,444
144
147
  unfold/templates/admin/index.html,sha256=9ey6IIXxBVTEkVSDiQw01AwvMbUnG_h0B08N1Zg3wTg,578
145
- unfold/templates/admin/login.html,sha256=fAY1FF3P0Zc4WYXh3CpZOMuyrr7Bfz29VxwD-MJ_vHg,4605
148
+ unfold/templates/admin/login.html,sha256=W07Dtr3-YQ-JP1jYKZMsBxrmO1u49A5R4UZyOUmZYfY,2465
146
149
  unfold/templates/admin/nav_sidebar.html,sha256=xvCaXOamXawmf80NhE0OwjjjuNwoyoePS--lsdqDeIE,772
147
150
  unfold/templates/admin/object_history.html,sha256=t-iJFQnpstowwsabGGA-FQjmcT1KIKhKLKbQ3iVELkk,4832
148
151
  unfold/templates/admin/pagination.html,sha256=-9kjc_lKEeqvDVHMrnTfnlXDxMSkM8GNRGZGuI9D8os,912
@@ -152,7 +155,7 @@ unfold/templates/auth/widgets/read_only_password_hash.html,sha256=MlaNXJ2PLEbv8N
152
155
  unfold/templates/registration/logged_out.html,sha256=oIdaqGcvIdBih3yNnUkXSEpvofRsBJ77obldnhcnP2U,997
153
156
  unfold/templates/registration/password_change_done.html,sha256=ITV6Fug4S6YG3WG-O1cm-sDAXTHEXPcNZ_w2x1IQFu8,1006
154
157
  unfold/templates/registration/password_change_form.html,sha256=-8AauxUHWHXVaokG269UsETY_FHKqU83Zx38ZzrAA1A,2159
155
- unfold/templates/unfold/components/button.html,sha256=PXYHCy5x_REPQSOukXiyT901D5KmoWoSfMWlMrUPSEA,670
158
+ unfold/templates/unfold/components/button.html,sha256=RlNNIa_JmcsNFH151ECHkbB2TxpgeCPRh-eW1Bc0Xtk,933
156
159
  unfold/templates/unfold/components/card.html,sha256=N9ld_SWpXdmaqAea9bboy0bTg1YqIkAhsJmOj7nd0qs,1353
157
160
  unfold/templates/unfold/components/chart/bar.html,sha256=nDdDCUXvFd793OpNgNPQo0vBmvYngMsQyPHVTf1vfOw,297
158
161
  unfold/templates/unfold/components/chart/cohort.html,sha256=L00WR-igYv0C3t2yT_nZqeI-M5gVHpoaGv5RooRojqU,2402
@@ -170,8 +173,8 @@ unfold/templates/unfold/components/tracker.html,sha256=krlvsb06lpfdOIANsyrBOoLq1
170
173
  unfold/templates/unfold/helpers/account_links.html,sha256=Tq30bAkOU8QRR6CaB1CvTfTgkoPP5dz2v0OHYq0pRSE,2348
171
174
  unfold/templates/unfold/helpers/actions_row.html,sha256=RqhZsxgIFR-r1casv5CueL81uxNl8rA3XuCMDP--zLA,2586
172
175
  unfold/templates/unfold/helpers/add_link.html,sha256=Z0TzUavXH8AQ7A-I0SQ79t-UI87dyP_PZEpsDrm13Q8,810
173
- unfold/templates/unfold/helpers/app_list.html,sha256=AoTyb-0jQTnnAtPmXtiN52oEaeIbdtQZgzqqZZhquOc,5744
174
- unfold/templates/unfold/helpers/app_list_default.html,sha256=LbyLT9xYgev0xXwprkXOghtqqVhcRwGS4CPXeJQnR-8,3918
176
+ unfold/templates/unfold/helpers/app_list.html,sha256=baydU9R_xmH9pWgs8B7PUcwTWcLxHDhD1ehs75c5PD0,5879
177
+ unfold/templates/unfold/helpers/app_list_default.html,sha256=0TR2ZTy0KUqa6YR8IgihA_4RQqBIFOroYpRHHIyD4H8,4015
175
178
  unfold/templates/unfold/helpers/attrs.html,sha256=Mwpj72kuwYj8hOT3J2T8qx6f1r_4xwwaS1slHA-82jI,166
176
179
  unfold/templates/unfold/helpers/boolean.html,sha256=kcSZr3siQeBWIy_jsx1tFf4m6IB3ooRnu8UUNQrh6so,569
177
180
  unfold/templates/unfold/helpers/breadcrumb_item.html,sha256=9T6ojN7LOXIlgwSwlIwHgy5U22eQYtarCqcmzsQIoPU,201
@@ -189,7 +192,7 @@ unfold/templates/unfold/helpers/edit_inline/tabular_heading.html,sha256=wvnpGFJV
189
192
  unfold/templates/unfold/helpers/edit_inline/tabular_row.html,sha256=eCyWEYvvDDCr9SR4_0ua5-GqCLIlFzgQYIZP0ip8cp8,2145
190
193
  unfold/templates/unfold/helpers/edit_inline/tabular_title.html,sha256=2sk1TRzpmwy8PPPMNdf6CJx0zVSk-I2q3yX8uEPjuxE,2710
191
194
  unfold/templates/unfold/helpers/empty_results.html,sha256=zN1XM6_9_Oj-inMZlDxEnicYfBRr4HhwS9ODAnMiRYc,1947
192
- unfold/templates/unfold/helpers/field.html,sha256=2q2M4dfisKJ9v8jt8gcq-iRf74t6H9W6xg16scZNF70,979
195
+ unfold/templates/unfold/helpers/field.html,sha256=KEs1SQRxzJ0x11zithlxVyv5zfQ9a_XGoJJ9AiWk1Vc,1038
193
196
  unfold/templates/unfold/helpers/field_readonly.html,sha256=4qtXjWE7SA2qZSTYLOv0lT4pQfD0TE34mvWQJY7jhS8,237
194
197
  unfold/templates/unfold/helpers/field_readonly_value.html,sha256=FI_CFEsCN7ELQux9gF-IaZ7nT7jyzidqwR2Med-E52g,504
195
198
  unfold/templates/unfold/helpers/fieldset_row.html,sha256=LriorPLXU4VmqstjX1oBc3T49H8CbhCrRxwQ7YfUSkI,1219
@@ -219,6 +222,7 @@ unfold/templates/unfold/helpers/pagination_current_item.html,sha256=4cZ2KLVcP0Y7
219
222
  unfold/templates/unfold/helpers/pagination_default.html,sha256=pseTrqaG5EOn_IpCy0GXNht3ickSkZYJ4lJaocZeI6A,496
220
223
  unfold/templates/unfold/helpers/pagination_ellipsis.html,sha256=8g0KUUKtqRkXx_EBLGtsJsiYQO4tPS3GazZjxT90e0M,56
221
224
  unfold/templates/unfold/helpers/pagination_infinite.html,sha256=QyHcYb36CeuiwpukC0Y553UC4LU2tPolGos-0mh7WP0,557
225
+ unfold/templates/unfold/helpers/pagination_inline.html,sha256=wFuXDvW1p-9OF1FSlOERkhP1Jt1WLzNfN7UkqsHtOQ4,1414
222
226
  unfold/templates/unfold/helpers/search.html,sha256=Pu2hxLGkN_NA-BU8_t4E7Q6uaY6hYTLoD8NZHyrcCaQ,1549
223
227
  unfold/templates/unfold/helpers/search_results.html,sha256=pQx7KoDMapWDusV88qe5hxlxicfP-S9iacji1Hq41Kc,661
224
228
  unfold/templates/unfold/helpers/site_branding.html,sha256=_pUyOvdjlV624eRq0wjpJkgXpn9DCDGc-0U6Mw0FupI,266
@@ -231,11 +235,14 @@ unfold/templates/unfold/helpers/tab_actions.html,sha256=Ir0HFxNAdZWdE6GuxaanSScN
231
235
  unfold/templates/unfold/helpers/tab_items.html,sha256=5kZcU7R9tZKKxVLahp2siZpZf7FhrluBH1dIAIaWoAg,3377
232
236
  unfold/templates/unfold/helpers/tab_list.html,sha256=mprad7Fu5ms1qGqjDl9HMmtfUodk43smd3IjagYOyr0,452
233
237
  unfold/templates/unfold/helpers/theme_switch.html,sha256=Y46KKpULH_G-fKQuc5LzfSB7Pubcgj_dBJPRMwZoWxE,2408
238
+ unfold/templates/unfold/helpers/unauthenticated_header.html,sha256=DNfZt_JDnMFwwo_SG0iYEB3I7eQIbwaB4QcpJGs1dtk,535
239
+ unfold/templates/unfold/helpers/unauthenticated_title.html,sha256=2aGnsdZbDV6yno9pb4sqEi15J7M9iLiMz3FY9F0Sgq4,387
234
240
  unfold/templates/unfold/helpers/userlinks.html,sha256=bJRDQXQ_0XgxLpfmZoNgU9xpn4X6T6LOAgEmzepFXOI,740
235
241
  unfold/templates/unfold/helpers/welcomemsg.html,sha256=Z3dDvozCJ5VhSVA_1go0F4ZD0lQYhCmoWqd_RM00pec,2019
236
242
  unfold/templates/unfold/layouts/base.html,sha256=e9T-vuPvrySHf23LLwRuTQXUg0Q4x-6gmT_yXghqc-I,278
237
243
  unfold/templates/unfold/layouts/base_simple.html,sha256=qUZ9YM24UHgWbmTl61zgN4_ty49P1FZJQ2siNbwnFnQ,1244
238
244
  unfold/templates/unfold/layouts/skeleton.html,sha256=2AWjJx6TxpYbXldwrXRbtyp9XTpAu6O0U_zcJtfYfWs,4684
245
+ unfold/templates/unfold/layouts/unauthenticated.html,sha256=Rh84psp8Ek-i1hVIiYz-HX7lyiQL7FnqA_uAp-D69DI,1022
239
246
  unfold/templates/unfold/templatetags/preserve_changelist_filters.html,sha256=sx2jUhogNY4emBhY8PqxQ6mXifbXQb_IQI9Hd0boJI0,111
240
247
  unfold/templates/unfold/widgets/clearable_file_input.html,sha256=8dXZnc6z2D2K08hqHsQwR5UJffcIRnmYBT02zmCOr9A,2191
241
248
  unfold/templates/unfold/widgets/clearable_file_input_small.html,sha256=zhnaDz72mJgMrq-nCPCMuR5tEJaFVfJyOJUAzR6tQWc,2624
@@ -249,6 +256,7 @@ unfold/templates/unfold/widgets/select.html,sha256=MyhlEO4sf7AUjOgH84rL76rhYM0WE
249
256
  unfold/templates/unfold/widgets/split_datetime.html,sha256=Hfv2PoHxPmV_21DmBFmMcR4WVP9vTV9SrfjVdliRci8,1074
250
257
  unfold/templates/unfold/widgets/split_datetime_vertical.html,sha256=39lZsRyRcKr8DIcy9oL39zC8nAHZTHwW6gyTYOKePrQ,806
251
258
  unfold/templates/unfold/widgets/split_money.html,sha256=AFLUBmzGbY-RXgsfz7gaDxVRhplaIPhXjg_hWYo9xcY,352
259
+ unfold/templates/unfold/widgets/text.html,sha256=jR_nrBN5A-evlX8aHpJplB_CG4aJblaVLMdp8z4-dG8,949
252
260
  unfold/templates/unfold/widgets/textarea.html,sha256=-ZLDGrtASero7L-J3VvTNq_KjPAZh_kLVw0Ow3awqXM,144
253
261
  unfold/templates/unfold/widgets/time.html,sha256=ih9wj8koTaHb9s1NGUmyN9rHvSAmqCMbti9ONDOIujg,122
254
262
  unfold/templates/unfold/widgets/url.html,sha256=IRLgW44VTKN7UrSWeywJwaxQhfG5jhhXuT-KTadKX58,304
@@ -277,13 +285,13 @@ unfold/templates/unfold_crispy/uni_form.html,sha256=l9UNCUrIycgJ0p_B6qhtO_YxdARy
277
285
  unfold/templates/unfold_crispy/whole_uni_form.html,sha256=ufXRKCIGqkqKFOsh166rpKUnHpFMyBV4eYUCRhs3iws,475
278
286
  unfold/templates/unfold_crispy/whole_uni_formset.html,sha256=CYksfG2hRUdi5n691KW2ih-FfBxpOU4qVBfbOvcu1zs,873
279
287
  unfold/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
280
- unfold/templatetags/unfold.py,sha256=wIooF34mIRmyN-9l_hKSMVYWNauH8kwL_q11J7OJ3vQ,17411
288
+ unfold/templatetags/unfold.py,sha256=Z4VYkTigW2DEURcyq8E7d8EkvCWl_TG_mNDmveE5K6k,18141
281
289
  unfold/templatetags/unfold_list.py,sha256=ayShOYEXcV3o7wKt3t2aFTWvg62Mb-WGlxjYVGgk3a0,14344
282
290
  unfold/typing.py,sha256=i7LM2LiwYTAjT5-OLDUPVn5b9X-DMmHnjlZG2toWwSE,692
283
291
  unfold/utils.py,sha256=lXKkvhaTxoTtd4p3bB0wHIZD26md6XzBcDkPL5bJGH8,6191
284
292
  unfold/views.py,sha256=FuYnMrlg6SegLUDDN6An__yZj8rchD_iBK8myieYhkA,1492
285
- unfold/widgets.py,sha256=z8bWwus1CYn20jp4f7tn_ChGUDCS563RZYp09I2kxIY,23216
286
- django_unfold-0.59.0.dist-info/LICENSE.md,sha256=Ltk_quRyyvV3J5v3brtOqmibeZSw2Hrb8bY1W3ya0Ik,1077
287
- django_unfold-0.59.0.dist-info/METADATA,sha256=AhBYGL06Dc5hTu3wW55BLYdrLmQxF_-NvvgX3cIibFY,7951
288
- django_unfold-0.59.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
289
- django_unfold-0.59.0.dist-info/RECORD,,
293
+ unfold/widgets.py,sha256=kBQ94omaglt0csjNbX4VFWL1rjb0vBFZeC2X6HOvHuY,24484
294
+ django_unfold-0.60.0.dist-info/LICENSE.md,sha256=Ltk_quRyyvV3J5v3brtOqmibeZSw2Hrb8bY1W3ya0Ik,1077
295
+ django_unfold-0.60.0.dist-info/METADATA,sha256=WUTbBoxXiw3YcvlNnKH5WzMcS0SFxpus6JweY1mUfPQ,8092
296
+ django_unfold-0.60.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
297
+ django_unfold-0.60.0.dist-info/RECORD,,
unfold/admin.py CHANGED
@@ -1,11 +1,18 @@
1
1
  from functools import update_wrapper
2
- from typing import Optional
2
+ from typing import Any, Optional
3
3
 
4
4
  from django import forms
5
5
  from django.contrib.admin import ModelAdmin as BaseModelAdmin
6
6
  from django.contrib.admin import StackedInline as BaseStackedInline
7
7
  from django.contrib.admin import TabularInline as BaseTabularInline
8
8
  from django.contrib.admin import display, helpers
9
+ from django.contrib.admin.options import InlineModelAdmin
10
+ from django.contrib.contenttypes.admin import (
11
+ GenericStackedInline as BaseGenericStackedInline,
12
+ )
13
+ from django.contrib.contenttypes.admin import (
14
+ GenericTabularInline as BaseGenericTabularInline,
15
+ )
9
16
  from django.db.models import BLANK_CHOICE_DASH, Model
10
17
  from django.http import HttpRequest, HttpResponse
11
18
  from django.shortcuts import redirect
@@ -16,8 +23,11 @@ from django.utils.translation import gettext_lazy as _
16
23
  from django.views import View
17
24
 
18
25
  from unfold.checks import UnfoldModelAdminChecks
19
- from unfold.fields import UnfoldAdminField, UnfoldAdminReadonlyField
20
- from unfold.forms import ActionForm
26
+ from unfold.forms import (
27
+ ActionForm,
28
+ PaginationGenericInlineFormSet,
29
+ PaginationInlineFormSet,
30
+ )
21
31
  from unfold.mixins import ActionModelAdminMixin, BaseModelAdminMixin
22
32
  from unfold.overrides import FORMFIELD_OVERRIDES_INLINE
23
33
  from unfold.typing import FieldsetsType
@@ -32,10 +42,6 @@ checkbox = UnfoldBooleanWidget(
32
42
  lambda value: False,
33
43
  )
34
44
 
35
- helpers.AdminField = UnfoldAdminField
36
-
37
- helpers.AdminReadonlyField = UnfoldAdminReadonlyField
38
-
39
45
 
40
46
  class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
41
47
  action_form = ActionForm
@@ -182,16 +188,42 @@ class ModelAdmin(BaseModelAdminMixin, ActionModelAdminMixin, BaseModelAdmin):
182
188
  def get_changelist(self, request, **kwargs):
183
189
  return ChangeList
184
190
 
191
+ def get_formset_kwargs(
192
+ self, request: HttpRequest, obj: Model, inline: InlineModelAdmin, prefix: str
193
+ ) -> dict[str, Any]:
194
+ formset_kwargs = super().get_formset_kwargs(request, obj, inline, prefix)
195
+ formset_kwargs["request"] = request
185
196
 
186
- class TabularInline(BaseModelAdminMixin, BaseTabularInline):
187
- formfield_overrides = FORMFIELD_OVERRIDES_INLINE
188
- readonly_preprocess_fields = {}
189
- ordering_field = None
190
- hide_ordering_field = False
197
+ if hasattr(inline, "per_page"):
198
+ formset_kwargs["per_page"] = inline.per_page
191
199
 
200
+ return formset_kwargs
192
201
 
193
- class StackedInline(BaseModelAdminMixin, BaseStackedInline):
202
+
203
+ class BaseInlineMixin:
194
204
  formfield_overrides = FORMFIELD_OVERRIDES_INLINE
195
205
  readonly_preprocess_fields = {}
196
206
  ordering_field = None
207
+ per_page = None
197
208
  hide_ordering_field = False
209
+ collapsible = False
210
+
211
+
212
+ class TabularInline(BaseInlineMixin, BaseModelAdminMixin, BaseTabularInline):
213
+ formset = PaginationInlineFormSet
214
+
215
+
216
+ class StackedInline(BaseInlineMixin, BaseModelAdminMixin, BaseStackedInline):
217
+ formset = PaginationInlineFormSet
218
+
219
+
220
+ class GenericStackedInline(
221
+ BaseInlineMixin, BaseModelAdminMixin, BaseGenericStackedInline
222
+ ):
223
+ formset = PaginationGenericInlineFormSet
224
+
225
+
226
+ class GenericTabularInline(
227
+ BaseInlineMixin, BaseModelAdminMixin, BaseGenericTabularInline
228
+ ):
229
+ formset = PaginationGenericInlineFormSet
@@ -12,10 +12,15 @@ from django.http import HttpRequest
12
12
  from django.utils.text import get_text_list
13
13
  from django.utils.translation import gettext_lazy as _
14
14
 
15
- from unfold.admin import StackedInline, TabularInline
16
-
17
- from .checks import NonrelatedModelAdminChecks
18
- from .forms import NonrelatedInlineModelFormSet, nonrelated_inline_formset_factory
15
+ from unfold.admin import (
16
+ StackedInline,
17
+ TabularInline,
18
+ )
19
+ from unfold.contrib.inlines.checks import NonrelatedModelAdminChecks
20
+ from unfold.contrib.inlines.forms import (
21
+ NonrelatedInlineModelFormSet,
22
+ nonrelated_inline_formset_factory,
23
+ )
19
24
 
20
25
 
21
26
  class NonrelatedInlineMixin:
@@ -135,8 +140,8 @@ class NonrelatedInlineMixin:
135
140
 
136
141
 
137
142
  class NonrelatedStackedInline(NonrelatedInlineMixin, StackedInline):
138
- pass
143
+ formset = NonrelatedInlineModelFormSet
139
144
 
140
145
 
141
146
  class NonrelatedTabularInline(NonrelatedInlineMixin, TabularInline):
142
- pass
147
+ formset = NonrelatedInlineModelFormSet
@@ -3,8 +3,10 @@ from typing import Any, Callable, Optional
3
3
  from django.db.models import Model, QuerySet
4
4
  from django.forms import BaseModelFormSet, ModelForm, modelformset_factory
5
5
 
6
+ from unfold.forms import PaginationFormSetMixin
6
7
 
7
- class NonrelatedInlineModelFormSet(BaseModelFormSet):
8
+
9
+ class NonrelatedInlineModelFormSet(PaginationFormSetMixin, BaseModelFormSet):
8
10
  def __init__(
9
11
  self,
10
12
  instance: Optional[Model] = None,
File without changes
@@ -0,0 +1,6 @@
1
+ from django.apps import AppConfig
2
+
3
+
4
+ class DefaultAppConfig(AppConfig):
5
+ name = "unfold.contrib.location_field"
6
+ label = "unfold_location_field"
@@ -0,0 +1,5 @@
1
+ <div class="map-widget flex flex-col gap-2">
2
+ {{ field_input }}
3
+
4
+ <div id="map_{{ field_name }}" class="border gap-2 h-72 max-w-2xl rounded-default shadow-xs"></div>
5
+ </div>
unfold/fields.py CHANGED
@@ -17,33 +17,24 @@ from django.utils.module_loading import import_string
17
17
  from django.utils.safestring import SafeText, mark_safe
18
18
  from django.utils.text import capfirst
19
19
 
20
- from unfold.mixins import BaseModelAdminMixin
21
20
  from unfold.settings import get_config
22
21
  from unfold.utils import display_for_field, prettify_json
23
- from unfold.widgets import CHECKBOX_LABEL_CLASSES, LABEL_CLASSES
22
+ from unfold.widgets import (
23
+ CHECKBOX_LABEL_CLASSES,
24
+ INPUT_CLASSES,
25
+ LABEL_CLASSES,
26
+ )
24
27
 
25
28
 
26
29
  class UnfoldAdminReadonlyField(helpers.AdminReadonlyField):
27
30
  def label_tag(self) -> SafeText:
28
- from .admin import ModelAdmin
29
-
30
- if not isinstance(self.model_admin, ModelAdmin) and not isinstance(
31
- self.model_admin, BaseModelAdminMixin
32
- ):
33
- return super().label_tag()
34
-
35
31
  attrs = {
36
32
  "class": " ".join(LABEL_CLASSES + ["mb-2"]),
37
33
  }
38
34
 
39
35
  label = self.field["label"]
40
36
 
41
- return format_html(
42
- "<label{}>{}{}</label>",
43
- flatatt(attrs),
44
- capfirst(label),
45
- self.form.label_suffix,
46
- )
37
+ return format_html("<label{}>{}</label>", flatatt(attrs), capfirst(label))
47
38
 
48
39
  def is_json(self) -> bool:
49
40
  field, obj, model_admin = (
@@ -174,12 +165,19 @@ class UnfoldAdminReadonlyField(helpers.AdminReadonlyField):
174
165
 
175
166
 
176
167
  class UnfoldAdminField(helpers.AdminField):
168
+ def __init__(self, *args, **kwargs):
169
+ super().__init__(*args, **kwargs)
170
+
171
+ try:
172
+ from location_field.widgets import LocationWidget
173
+
174
+ if isinstance(self.field.field.widget, LocationWidget):
175
+ self.field.field.widget.attrs["class"] = " ".join(INPUT_CLASSES)
176
+ except ImportError:
177
+ pass
178
+
177
179
  def label_tag(self) -> SafeText:
178
180
  classes = []
179
- if not self.field.field.widget.__class__.__name__.startswith(
180
- "Unfold"
181
- ) and not self.field.field.widget.template_name.startswith("unfold"):
182
- return super().label_tag()
183
181
 
184
182
  # TODO load config from current AdminSite (override Fieldline.__iter__ method)
185
183
  for lang, flag in get_config()["EXTENSIONS"]["modeltranslation"][
unfold/forms.py CHANGED
@@ -1,3 +1,4 @@
1
+ from collections.abc import Generator
1
2
  from typing import Optional
2
3
 
3
4
  from django import forms
@@ -11,14 +12,23 @@ from django.contrib.auth.forms import (
11
12
  AdminPasswordChangeForm as BaseAdminPasswordChangeForm,
12
13
  )
13
14
  from django.contrib.auth.models import User
15
+ from django.contrib.contenttypes.forms import BaseGenericInlineFormSet
16
+ from django.core.paginator import Page, Paginator
17
+ from django.db.models import QuerySet
18
+ from django.forms import BaseInlineFormSet
19
+ from django.http import HttpRequest
20
+
21
+ from unfold.fields import UnfoldAdminField, UnfoldAdminReadonlyField
14
22
 
15
23
  try:
16
24
  from django.contrib.auth.forms import AdminUserCreationForm as BaseUserCreationForm
17
25
  except ImportError:
18
26
  from django.contrib.auth.forms import UserCreationForm as BaseUserCreationForm
27
+ from django.contrib.admin.helpers import AdminForm as BaseAdminForm
28
+ from django.contrib.admin.helpers import Fieldline as BaseFieldline
29
+ from django.contrib.admin.helpers import Fieldset as BaseFieldset
19
30
  from django.contrib.auth.forms import ReadOnlyPasswordHashWidget
20
31
  from django.contrib.auth.forms import UserChangeForm as BaseUserChangeForm
21
- from django.http import HttpRequest
22
32
  from django.utils.safestring import mark_safe
23
33
  from django.utils.translation import gettext_lazy as _
24
34
 
@@ -146,3 +156,87 @@ class AdminOwnPasswordChangeForm(BaseAdminOwnPasswordChangeForm):
146
156
  self.fields["old_password"].widget.attrs["class"] = " ".join(INPUT_CLASSES)
147
157
  self.fields["new_password1"].widget.attrs["class"] = " ".join(INPUT_CLASSES)
148
158
  self.fields["new_password2"].widget.attrs["class"] = " ".join(INPUT_CLASSES)
159
+
160
+
161
+ class AdminForm(BaseAdminForm):
162
+ def __iter__(self) -> Generator["Fieldset", None, None]:
163
+ for name, options in self.fieldsets:
164
+ yield Fieldset(
165
+ self.form,
166
+ name,
167
+ readonly_fields=self.readonly_fields,
168
+ model_admin=self.model_admin,
169
+ **options,
170
+ )
171
+
172
+
173
+ class Fieldset(BaseFieldset):
174
+ def __iter__(self) -> Generator["Fieldline", None, None]:
175
+ for field in self.fields:
176
+ yield Fieldline(
177
+ self.form, field, self.readonly_fields, model_admin=self.model_admin
178
+ )
179
+
180
+
181
+ class Fieldline(BaseFieldline):
182
+ def __iter__(
183
+ self,
184
+ ) -> Generator["UnfoldAdminReadonlyField | UnfoldAdminField", None, None]:
185
+ for i, field in enumerate(self.fields):
186
+ if field in self.readonly_fields:
187
+ yield UnfoldAdminReadonlyField(
188
+ self.form, field, is_first=(i == 0), model_admin=self.model_admin
189
+ )
190
+ else:
191
+ yield UnfoldAdminField(self.form, field, is_first=(i == 0))
192
+
193
+
194
+ class PaginationFormSetMixin:
195
+ queryset: Optional[QuerySet] = None
196
+ request: Optional[HttpRequest] = None
197
+ per_page: Optional[int] = None
198
+
199
+ def __init__(
200
+ self,
201
+ request: Optional[HttpRequest] = None,
202
+ per_page: Optional[int] = None,
203
+ *args,
204
+ **kwargs,
205
+ ):
206
+ self.request = request
207
+ self.per_page = per_page
208
+
209
+ super().__init__(*args, **kwargs)
210
+
211
+ if self.per_page:
212
+ self.paginator = Paginator(self.queryset, self.per_page)
213
+ self.page = self.get_page(self.paginator, self.get_page_num())
214
+ self._queryset = self.page.object_list
215
+
216
+ def get_pagination_key(self) -> str:
217
+ return f"{self.prefix}-page"
218
+
219
+ def get_page_num(self) -> int:
220
+ page = self.request.GET.get(self.get_pagination_key())
221
+ if page and page.isnumeric() and page > "0":
222
+ return int(page)
223
+
224
+ page = self.request.POST.get(self.get_pagination_key())
225
+ if page and page.isnumeric() and page > "0":
226
+ return int(page)
227
+
228
+ return 1
229
+
230
+ def get_page(self, paginator: Paginator, page: int) -> Page:
231
+ if page <= paginator.num_pages:
232
+ return paginator.page(page)
233
+
234
+ return paginator.page(1)
235
+
236
+
237
+ class PaginationInlineFormSet(PaginationFormSetMixin, BaseInlineFormSet):
238
+ pass
239
+
240
+
241
+ class PaginationGenericInlineFormSet(PaginationFormSetMixin, BaseGenericInlineFormSet):
242
+ pass
@@ -1,6 +1,7 @@
1
1
  import copy
2
- from typing import Optional
2
+ from typing import Any, Optional
3
3
 
4
+ from django.contrib.admin import helpers
4
5
  from django.contrib.admin.sites import AdminSite
5
6
  from django.contrib.admin.widgets import RelatedFieldWidgetWrapper
6
7
  from django.db import models
@@ -27,6 +28,19 @@ class BaseModelAdminMixin:
27
28
 
28
29
  super().__init__(model, admin_site)
29
30
 
31
+ def changeform_view(
32
+ self,
33
+ request: HttpRequest,
34
+ object_id: Optional[str] = None,
35
+ form_url: str = "",
36
+ extra_context: Optional[dict[str, bool]] = None,
37
+ ) -> Any:
38
+ from unfold.forms import AdminForm, Fieldline
39
+
40
+ helpers.AdminForm = AdminForm
41
+ helpers.Fieldline = Fieldline
42
+ return super().changeform_view(request, object_id, form_url, extra_context)
43
+
30
44
  def formfield_for_choice_field(
31
45
  self, db_field: Field, request: HttpRequest, **kwargs
32
46
  ) -> TypedChoiceField:
unfold/sites.py CHANGED
@@ -4,15 +4,12 @@ from typing import Any, Callable, Optional, Union
4
4
  from urllib.parse import parse_qs, urlparse
5
5
 
6
6
  from django.contrib.admin import AdminSite
7
- from django.contrib.auth import REDIRECT_FIELD_NAME
8
7
  from django.core.validators import EMPTY_VALUES
9
8
  from django.http import HttpRequest, HttpResponse
10
9
  from django.template.response import TemplateResponse
11
10
  from django.urls import URLPattern, path, reverse, reverse_lazy
12
- from django.utils.decorators import method_decorator
13
11
  from django.utils.functional import lazy
14
12
  from django.utils.module_loading import import_string
15
- from django.views.decorators.cache import never_cache
16
13
 
17
14
  from unfold.dataclasses import DropdownItem, Favicon
18
15
 
@@ -91,6 +88,9 @@ class UnfoldAdminSite(AdminSite):
91
88
  "site_icon": self._get_theme_images("SITE_ICON", request),
92
89
  "site_symbol": self._get_config("SITE_SYMBOL", request),
93
90
  "site_favicons": self._get_favicons("SITE_FAVICONS", request),
91
+ "login_image": self._get_value(
92
+ get_config(self.settings_name)["LOGIN"].get("image"), request
93
+ ),
94
94
  "show_history": self._get_config("SHOW_HISTORY", request),
95
95
  "show_view_on_site": self._get_config("SHOW_VIEW_ON_SITE", request),
96
96
  "show_languages": self._get_config("SHOW_LANGUAGES", request),
@@ -198,32 +198,6 @@ class UnfoldAdminSite(AdminSite):
198
198
  },
199
199
  )
200
200
 
201
- @method_decorator(never_cache)
202
- @login_not_required
203
- def login(
204
- self, request: HttpRequest, extra_context: Optional[dict[str, Any]] = None
205
- ) -> HttpResponse:
206
- extra_context = {} if extra_context is None else extra_context
207
- image = self._get_value(
208
- get_config(self.settings_name)["LOGIN"].get("image"), request
209
- )
210
-
211
- redirect_field_name = self._get_value(
212
- get_config(self.settings_name)["LOGIN"].get("redirect_after"), request
213
- )
214
-
215
- if image not in EMPTY_VALUES:
216
- extra_context.update(
217
- {
218
- "image": image,
219
- }
220
- )
221
-
222
- if redirect_field_name not in EMPTY_VALUES:
223
- extra_context.update({REDIRECT_FIELD_NAME: redirect_field_name})
224
-
225
- return super().login(request, extra_context)
226
-
227
201
  def password_change(
228
202
  self, request: HttpRequest, extra_context: Optional[dict[str, Any]] = None
229
203
  ) -> HttpResponse:
@@ -80,8 +80,8 @@
80
80
  // );
81
81
 
82
82
  const siblings = $this
83
- .parent()
84
- .nextAll(".view-related, .change-related, .delete-related");
83
+ .closest(".related-widget-wrapper")
84
+ .find(".view-related, .change-related, .delete-related");
85
85
 
86
86
  if (!siblings.length) {
87
87
  return;