wagtail 6.0.2__py3-none-any.whl → 6.1rc1__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 (355) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/admin/checks.py +51 -0
  3. wagtail/admin/compare.py +1 -1
  4. wagtail/admin/filters.py +70 -1
  5. wagtail/admin/forms/account.py +1 -1
  6. wagtail/admin/forms/collections.py +15 -0
  7. wagtail/admin/forms/pages.py +49 -0
  8. wagtail/admin/locale/de/LC_MESSAGES/django.mo +0 -0
  9. wagtail/admin/locale/de/LC_MESSAGES/django.po +5 -5
  10. wagtail/admin/locale/en/LC_MESSAGES/django.po +474 -385
  11. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +3 -3
  12. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  13. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +73 -2
  14. wagtail/admin/locale/ro/LC_MESSAGES/django.mo +0 -0
  15. wagtail/admin/locale/ro/LC_MESSAGES/django.po +3 -3
  16. wagtail/admin/panels/comment_panel.py +1 -1
  17. wagtail/admin/panels/field_panel.py +1 -1
  18. wagtail/admin/rich_text/converters/editor_html.py +3 -1
  19. wagtail/admin/rich_text/editors/draftail/__init__.py +28 -2
  20. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  21. wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
  22. wagtail/admin/static/wagtailadmin/images/favicon.ico +0 -0
  23. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  24. wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
  25. wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
  26. wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
  27. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  28. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  29. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +1 -1
  30. wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
  31. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  32. wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
  33. wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
  34. wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
  35. wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
  36. wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
  37. wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
  38. wagtail/admin/static/wagtailadmin/js/preview-panel.js +1 -1
  39. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  40. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  41. wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
  42. wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
  43. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  44. wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
  45. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  46. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  47. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  48. wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +4 -4
  49. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  50. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  51. wagtail/admin/staticfiles.py +1 -0
  52. wagtail/admin/templates/wagtailadmin/base.html +1 -0
  53. wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +3 -1
  54. wagtail/admin/templates/wagtailadmin/collections/index_results.html +10 -0
  55. wagtail/admin/templates/wagtailadmin/generic/base.html +1 -9
  56. wagtail/admin/templates/wagtailadmin/generic/form.html +3 -2
  57. wagtail/admin/templates/wagtailadmin/generic/history/action_cell.html +27 -0
  58. wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +3 -3
  59. wagtail/admin/templates/wagtailadmin/icons/keyboard.svg +1 -0
  60. wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +3 -1
  61. wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -14
  62. wagtail/admin/templates/wagtailadmin/pages/action_menu/save_draft.html +3 -1
  63. wagtail/admin/templates/wagtailadmin/pages/choose_parent.html +17 -0
  64. wagtail/admin/templates/wagtailadmin/pages/explorable_index.html +8 -0
  65. wagtail/admin/templates/wagtailadmin/pages/history.html +1 -61
  66. wagtail/admin/templates/wagtailadmin/pages/index.html +1 -3
  67. wagtail/admin/templates/wagtailadmin/pages/listing/_locked_indicator.html +2 -2
  68. wagtail/admin/templates/wagtailadmin/pages/listing/_page_title_column_header.html +25 -27
  69. wagtail/admin/templates/wagtailadmin/pages/page_listing_header.html +2 -1
  70. wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
  71. wagtail/admin/templates/wagtailadmin/panels/publishing/schedule_publishing_panel.html +3 -1
  72. wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +1 -1
  73. wagtail/admin/templates/wagtailadmin/shared/active_filters.html +2 -1
  74. wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +8 -0
  75. wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
  76. wagtail/admin/templates/wagtailadmin/shared/headers/page_edit_header.html +1 -1
  77. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +21 -9
  78. wagtail/admin/templates/wagtailadmin/shared/human_readable_date.html +1 -1
  79. wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +29 -0
  80. wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +2 -1
  81. wagtail/admin/templates/wagtailadmin/skeleton.html +2 -1
  82. wagtail/admin/templates/wagtailadmin/tables/related_objects_cell.html +9 -0
  83. wagtail/admin/templates/wagtailadmin/tables/title_cell.html +9 -7
  84. wagtail/admin/templates/wagtailadmin/widgets/draftail_rich_text_area.html +1 -1
  85. wagtail/admin/templates/wagtailadmin/workflows/create.html +6 -23
  86. wagtail/admin/templates/wagtailadmin/workflows/create_task.html +6 -15
  87. wagtail/admin/templates/wagtailadmin/workflows/edit.html +6 -23
  88. wagtail/admin/templates/wagtailadmin/workflows/edit_task.html +6 -13
  89. wagtail/admin/templates/wagtailadmin/workflows/includes/task_usage_cell.html +4 -4
  90. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_tasks_cell.html +18 -0
  91. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_title_cell.html +7 -0
  92. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_used_by_cell.html +25 -0
  93. wagtail/admin/templates/wagtailadmin/workflows/index.html +0 -99
  94. wagtail/admin/templates/wagtailadmin/workflows/index_results.html +10 -0
  95. wagtail/admin/templates/wagtailadmin/workflows/task_index.html +0 -30
  96. wagtail/admin/templates/wagtailadmin/workflows/task_index_results.html +10 -0
  97. wagtail/admin/templates/wagtailadmin/workflows/usage.html +1 -1
  98. wagtail/admin/templatetags/wagtailadmin_tags.py +116 -39
  99. wagtail/admin/tests/pages/test_create_page.py +10 -4
  100. wagtail/admin/tests/pages/test_custom_listing.py +37 -0
  101. wagtail/admin/tests/pages/test_edit_page.py +6 -6
  102. wagtail/admin/tests/pages/test_explorer_view.py +19 -18
  103. wagtail/admin/tests/pages/test_move_page.py +1 -1
  104. wagtail/admin/tests/pages/test_page_usage.py +50 -2
  105. wagtail/admin/tests/pages/test_parent_page_chooser_view.py +119 -0
  106. wagtail/admin/tests/pages/test_preview.py +18 -4
  107. wagtail/admin/tests/test_account_management.py +20 -1
  108. wagtail/admin/tests/test_audit_log.py +172 -5
  109. wagtail/admin/tests/test_checks.py +92 -0
  110. wagtail/admin/tests/test_collections_views.py +19 -5
  111. wagtail/admin/tests/test_compare.py +6 -6
  112. wagtail/admin/tests/test_dashboard.py +404 -0
  113. wagtail/admin/tests/test_dbwhitelister.py +4 -5
  114. wagtail/admin/tests/test_edit_handlers.py +2 -2
  115. wagtail/admin/tests/test_keyboard_shortcuts.py +84 -0
  116. wagtail/admin/tests/test_page_chooser.py +31 -18
  117. wagtail/admin/tests/test_privacy.py +36 -2
  118. wagtail/admin/tests/test_rich_text.py +168 -23
  119. wagtail/admin/tests/test_templatetags.py +411 -43
  120. wagtail/admin/tests/test_views.py +4 -2
  121. wagtail/admin/tests/test_workflows.py +531 -9
  122. wagtail/admin/tests/tests.py +3 -1
  123. wagtail/admin/tests/ui/test_tables.py +48 -1
  124. wagtail/admin/tests/viewsets/test_model_viewset.py +126 -29
  125. wagtail/admin/ui/side_panels.py +3 -1
  126. wagtail/admin/ui/tables/__init__.py +13 -1
  127. wagtail/admin/ui/tables/pages.py +17 -6
  128. wagtail/admin/urls/__init__.py +8 -3
  129. wagtail/admin/urls/pages.py +5 -0
  130. wagtail/admin/urls/workflows.py +10 -0
  131. wagtail/admin/views/chooser.py +20 -24
  132. wagtail/admin/views/collections.py +17 -1
  133. wagtail/admin/views/generic/base.py +31 -4
  134. wagtail/admin/views/generic/history.py +220 -51
  135. wagtail/admin/views/generic/mixins.py +7 -4
  136. wagtail/admin/views/generic/models.py +54 -38
  137. wagtail/admin/views/generic/multiple_upload.py +17 -8
  138. wagtail/admin/views/generic/usage.py +17 -11
  139. wagtail/admin/views/home.py +15 -12
  140. wagtail/admin/views/mixins.py +30 -0
  141. wagtail/admin/views/pages/choose_parent.py +73 -0
  142. wagtail/admin/views/pages/history.py +54 -66
  143. wagtail/admin/views/pages/listing.py +187 -106
  144. wagtail/admin/views/pages/usage.py +6 -1
  145. wagtail/admin/views/pages/utils.py +70 -1
  146. wagtail/admin/views/workflows.py +150 -21
  147. wagtail/admin/viewsets/model.py +2 -2
  148. wagtail/admin/viewsets/pages.py +77 -0
  149. wagtail/admin/wagtail_hooks.py +40 -2
  150. wagtail/admin/widgets/button.py +10 -9
  151. wagtail/api/v2/filters.py +1 -1
  152. wagtail/api/v2/tests/test_pages.py +1 -1
  153. wagtail/blocks/base.py +18 -9
  154. wagtail/blocks/field_block.py +9 -7
  155. wagtail/blocks/list_block.py +16 -6
  156. wagtail/blocks/static_block.py +3 -0
  157. wagtail/blocks/stream_block.py +58 -23
  158. wagtail/blocks/struct_block.py +15 -9
  159. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +39 -47
  160. wagtail/contrib/forms/models.py +5 -5
  161. wagtail/contrib/forms/templates/wagtailforms/list_submissions.html +44 -33
  162. wagtail/contrib/forms/templates/wagtailforms/submissions_index.html +2 -63
  163. wagtail/contrib/forms/tests/test_models.py +26 -0
  164. wagtail/contrib/forms/urls.py +6 -0
  165. wagtail/contrib/forms/views.py +52 -49
  166. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.mo +0 -0
  167. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +3 -3
  168. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +34 -42
  169. wagtail/contrib/redirects/signal_handlers.py +1 -1
  170. wagtail/contrib/redirects/templates/wagtailredirects/index.html +1 -36
  171. wagtail/contrib/redirects/templates/wagtailredirects/index_results.html +18 -0
  172. wagtail/contrib/redirects/templates/wagtailredirects/redirect_target_cell.html +8 -0
  173. wagtail/contrib/redirects/tests/test_import_command.py +1 -1
  174. wagtail/contrib/redirects/tests/test_redirects.py +79 -8
  175. wagtail/contrib/redirects/urls.py +2 -1
  176. wagtail/contrib/redirects/views.py +85 -55
  177. wagtail/contrib/search_promotions/admin_urls.py +2 -1
  178. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +41 -64
  179. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +1 -16
  180. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index_results.html +11 -0
  181. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/list.html +0 -51
  182. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/results.html +3 -16
  183. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/search_promotion_column.html +15 -0
  184. wagtail/contrib/search_promotions/tests.py +122 -9
  185. wagtail/contrib/search_promotions/views.py +66 -65
  186. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
  187. wagtail/contrib/settings/registry.py +10 -5
  188. wagtail/contrib/settings/tests/generic/test_admin.py +9 -0
  189. wagtail/contrib/settings/tests/site_specific/test_admin.py +10 -1
  190. wagtail/contrib/settings/tests/site_specific/test_model.py +3 -3
  191. wagtail/contrib/settings/tests/site_specific/test_templates.py +1 -1
  192. wagtail/contrib/settings/views.py +3 -1
  193. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
  194. wagtail/contrib/simple_translation/tests/test_wagtail_hooks.py +2 -2
  195. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
  196. wagtail/contrib/table_block/blocks.py +1 -1
  197. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  198. wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
  199. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
  200. wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
  201. wagtail/coreutils.py +3 -2
  202. wagtail/documents/admin_urls.py +2 -2
  203. wagtail/documents/locale/en/LC_MESSAGES/django.po +22 -22
  204. wagtail/documents/migrations/0013_delete_uploadeddocument.py +16 -0
  205. wagtail/documents/models.py +1 -20
  206. wagtail/documents/rich_text/__init__.py +11 -7
  207. wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
  208. wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
  209. wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
  210. wagtail/documents/templates/wagtaildocs/documents/index.html +0 -16
  211. wagtail/documents/tests/test_admin_views.py +155 -23
  212. wagtail/documents/tests/test_collection_privacy.py +55 -1
  213. wagtail/documents/tests/test_rich_text.py +14 -0
  214. wagtail/documents/views/documents.py +25 -22
  215. wagtail/documents/views/multiple.py +6 -7
  216. wagtail/documents/views/serve.py +16 -1
  217. wagtail/documents/wagtail_hooks.py +20 -15
  218. wagtail/embeds/blocks.py +5 -0
  219. wagtail/embeds/locale/en/LC_MESSAGES/django.po +2 -2
  220. wagtail/embeds/rich_text/__init__.py +1 -1
  221. wagtail/embeds/tests/test_rich_text.py +14 -0
  222. wagtail/embeds/wagtail_hooks.py +4 -14
  223. wagtail/fields.py +3 -48
  224. wagtail/images/admin_urls.py +2 -2
  225. wagtail/images/check_files/wagtail.jpg +0 -0
  226. wagtail/images/check_files/wagtail.png +0 -0
  227. wagtail/images/fields.py +2 -0
  228. wagtail/images/image_operations.py +1 -1
  229. wagtail/images/locale/en/LC_MESSAGES/django.po +33 -45
  230. wagtail/images/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  231. wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +4 -0
  232. wagtail/images/migrations/0026_delete_uploadedimage.py +16 -0
  233. wagtail/images/models.py +49 -43
  234. wagtail/images/rich_text/__init__.py +18 -8
  235. wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
  236. wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
  237. wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
  238. wagtail/images/templates/wagtailimages/images/image_listing_header.html +6 -0
  239. wagtail/images/templates/wagtailimages/images/index.html +11 -51
  240. wagtail/images/tests/test_admin_views.py +119 -62
  241. wagtail/images/tests/test_image_operations.py +10 -0
  242. wagtail/images/tests/test_models.py +35 -33
  243. wagtail/images/tests/test_rich_text.py +14 -0
  244. wagtail/images/tests/utils.py +1 -1
  245. wagtail/images/views/images.py +35 -64
  246. wagtail/images/views/multiple.py +6 -7
  247. wagtail/images/wagtail_hooks.py +4 -14
  248. wagtail/locale/en/LC_MESSAGES/django.po +150 -136
  249. wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
  250. wagtail/locales/tests.py +18 -3
  251. wagtail/locales/views.py +0 -1
  252. wagtail/management/commands/rebuild_references_index.py +3 -1
  253. wagtail/migrations/0092_alter_collectionviewrestriction_password_and_more.py +33 -0
  254. wagtail/migrations/0093_uploadedfile.py +53 -0
  255. wagtail/models/__init__.py +147 -32
  256. wagtail/models/i18n.py +1 -1
  257. wagtail/models/{collections.py → media.py} +33 -2
  258. wagtail/models/reference_index.py +1 -1
  259. wagtail/models/view_restrictions.py +10 -3
  260. wagtail/project_template/project_name/settings/base.py +6 -0
  261. wagtail/project_template/requirements.txt +1 -1
  262. wagtail/rich_text/__init__.py +25 -8
  263. wagtail/rich_text/pages.py +19 -8
  264. wagtail/rich_text/rewriters.py +140 -68
  265. wagtail/search/backends/database/mysql/mysql.py +3 -3
  266. wagtail/search/backends/database/postgres/postgres.py +3 -3
  267. wagtail/search/backends/database/sqlite/sqlite.py +2 -2
  268. wagtail/search/backends/elasticsearch7.py +4 -0
  269. wagtail/search/locale/en/LC_MESSAGES/django.po +3 -3
  270. wagtail/search/tests/test_postgres_backend.py +50 -0
  271. wagtail/sites/locale/en/LC_MESSAGES/django.po +8 -8
  272. wagtail/sites/tests.py +35 -9
  273. wagtail/sites/views.py +3 -1
  274. wagtail/snippets/locale/de/LC_MESSAGES/django.mo +0 -0
  275. wagtail/snippets/locale/de/LC_MESSAGES/django.po +5 -6
  276. wagtail/snippets/locale/en/LC_MESSAGES/django.po +16 -56
  277. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  278. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  279. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/publish.html +3 -1
  280. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/save.html +3 -1
  281. wagtail/snippets/templates/wagtailsnippets/snippets/create.html +1 -1
  282. wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +1 -1
  283. wagtail/snippets/tests/test_preview.py +13 -2
  284. wagtail/snippets/tests/test_snippets.py +41 -16
  285. wagtail/snippets/tests/test_viewset.py +63 -18
  286. wagtail/snippets/tests/test_workflows.py +12 -0
  287. wagtail/snippets/views/snippets.py +1 -40
  288. wagtail/templatetags/wagtailcore_tags.py +1 -1
  289. wagtail/test/demosite/models.py +1 -1
  290. wagtail/test/middleware.py +14 -1
  291. wagtail/test/testapp/fixtures/test.json +20 -0
  292. wagtail/test/testapp/migrations/0001_squashed_0073_revisablechildmodel_secret_text.py +8 -8
  293. wagtail/test/testapp/migrations/0023_snippetchoosermodel_full_featured.py +1 -0
  294. wagtail/test/testapp/migrations/0034_custompermissionmodel.py +44 -0
  295. wagtail/test/testapp/migrations/0035_modelwithcustommanager.py +30 -0
  296. wagtail/test/testapp/migrations/0036_complexdefaultstreampage.py +28 -0
  297. wagtail/test/testapp/models.py +79 -2
  298. wagtail/test/testapp/templates/tests/custom_docs_password_required.html +10 -0
  299. wagtail/test/testapp/templates/tests/custom_page_password_required.html +10 -0
  300. wagtail/test/testapp/views.py +24 -2
  301. wagtail/test/testapp/wagtail_hooks.py +19 -0
  302. wagtail/test/utils/wagtail_tests.py +2 -2
  303. wagtail/tests/test_blocks.py +262 -1
  304. wagtail/tests/test_migrations.py +1 -1
  305. wagtail/tests/test_page_model.py +77 -0
  306. wagtail/tests/test_page_privacy.py +18 -1
  307. wagtail/tests/test_rich_text.py +95 -5
  308. wagtail/tests/test_streamfield.py +43 -0
  309. wagtail/tests/test_utils.py +8 -2
  310. wagtail/tests/test_views.py +52 -1
  311. wagtail/tests/test_whitelist.py +7 -7
  312. wagtail/users/forms.py +3 -1
  313. wagtail/users/locale/en/LC_MESSAGES/django.po +124 -96
  314. wagtail/users/migrations/0013_userprofile_density.py +23 -0
  315. wagtail/users/models.py +14 -3
  316. wagtail/users/templates/wagtailusers/groups/create.html +1 -7
  317. wagtail/users/templates/wagtailusers/groups/edit.html +1 -13
  318. wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +46 -2
  319. wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -2
  320. wagtail/users/templates/wagtailusers/users/create.html +1 -9
  321. wagtail/users/templates/wagtailusers/users/edit.html +1 -9
  322. wagtail/users/templates/wagtailusers/users/index.html +2 -5
  323. wagtail/users/templates/wagtailusers/users/index_results.html +3 -13
  324. wagtail/users/templates/wagtailusers/users/user_cell.html +9 -0
  325. wagtail/users/templatetags/wagtailusers_tags.py +107 -20
  326. wagtail/users/tests/test_admin_views.py +669 -90
  327. wagtail/users/views/groups.py +58 -61
  328. wagtail/users/views/users.py +211 -92
  329. wagtail/users/wagtail_hooks.py +6 -38
  330. wagtail/users/widgets.py +3 -5
  331. wagtail/utils/text.py +1 -1
  332. wagtail/views.py +5 -9
  333. wagtail/whitelist.py +1 -1
  334. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/METADATA +4 -5
  335. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/RECORD +339 -320
  336. wagtail/admin/static/wagtailadmin/js/page-editor.js +0 -1
  337. wagtail/admin/static/wagtailadmin/js/vendor/mousetrap.min.js +0 -1
  338. wagtail/admin/static/wagtailadmin/js/vendor/urlify.js +0 -1
  339. wagtail/admin/static/wagtailadmin/js/vendor/xregexp.min.js +0 -1
  340. wagtail/admin/templates/wagtailadmin/collections/index.html +0 -34
  341. wagtail/admin/templates/wagtailadmin/pages/revisions/_actions.html +0 -22
  342. wagtail/admin/templates/wagtailadmin/shared/page_breadcrumbs.html +0 -55
  343. wagtail/admin/tests/pages/test_dashboard.py +0 -172
  344. wagtail/contrib/redirects/templates/wagtailredirects/results.html +0 -23
  345. wagtail/documents/templates/wagtaildocs/documents/list.html +0 -2
  346. wagtail/search/tests/test_postgres_stemming.py +0 -40
  347. wagtail/sites/templates/wagtailsites/create.html +0 -6
  348. wagtail/sites/templates/wagtailsites/edit.html +0 -6
  349. wagtail/snippets/templates/wagtailsnippets/snippets/revisions/_actions.html +0 -36
  350. wagtail/users/templates/wagtailusers/users/list.html +0 -62
  351. wagtail/users/urls/users.py +0 -12
  352. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/LICENSE +0 -0
  353. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/WHEEL +0 -0
  354. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/entry_points.txt +0 -0
  355. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/top_level.txt +0 -0
@@ -100,7 +100,7 @@ def wagtail_release_notes_path():
100
100
  def wagtail_feature_release_whats_new_link():
101
101
  major, minor, patch, release, num = VERSION
102
102
  if release == "final":
103
- return f"https://guide.wagtail.org/en-latest/releases/new-in-wagtail-{major}-{minor}/"
103
+ return f"https://guide.wagtail.org/en-{major}.{minor}.x/releases/new-in-wagtail-{major}-{minor}/"
104
104
  return "https://guide.wagtail.org/en-latest/releases/latest/"
105
105
 
106
106
 
@@ -471,7 +471,7 @@ class EventPage(Page):
471
471
 
472
472
  def get_event_index(self):
473
473
  # Find closest ancestor which is an event index
474
- return EventIndexPage.objects.ancester_of(self).last()
474
+ return EventIndexPage.objects.ancestor_of(self).last()
475
475
 
476
476
 
477
477
  class EventPageCarouselItem(Orderable, AbstractCarouselItem):
@@ -1,6 +1,9 @@
1
- from django.http import HttpResponseForbidden
1
+ from django.http import Http404, HttpResponse, HttpResponseForbidden
2
2
  from django.utils.deprecation import MiddlewareMixin
3
3
 
4
+ from wagtail.models import Page
5
+ from wagtail.views import serve
6
+
4
7
 
5
8
  class BlockDodgyUserAgentMiddleware(MiddlewareMixin):
6
9
  # Used to test that we're correctly handling responses returned from middleware during page
@@ -16,3 +19,13 @@ class BlockDodgyUserAgentMiddleware(MiddlewareMixin):
16
19
  and request.headers.get("user-agent") == "EvilHacker"
17
20
  ):
18
21
  return HttpResponseForbidden("Forbidden")
22
+
23
+
24
+ class SimplePageViewInterceptorMiddleware(MiddlewareMixin):
25
+ def process_view(self, request, view_func, view_args, view_kwargs):
26
+ if serve == view_func:
27
+ page = Page.find_for_request(request, *view_args, **view_kwargs)
28
+ if page is None:
29
+ raise Http404
30
+ elif page.content == "Intercept me":
31
+ return HttpResponse("Intercepted")
@@ -878,6 +878,15 @@
878
878
  "file": "documents/test.pdf"
879
879
  }
880
880
  },
881
+ {
882
+ "pk": 2,
883
+ "model": "wagtaildocs.Document",
884
+ "fields": {
885
+ "title": "another test document",
886
+ "created_at": "2020-01-01T12:00:00.000Z",
887
+ "file": "documents/another_test.pdf"
888
+ }
889
+ },
881
890
  {
882
891
  "pk": 1,
883
892
  "model": "wagtailcore.pageviewrestriction",
@@ -915,6 +924,17 @@
915
924
  "created_at": "2014-01-01T12:00:00.000Z"
916
925
  }
917
926
  },
927
+ {
928
+ "pk": 2,
929
+ "model": "wagtailimages.image",
930
+ "fields": {
931
+ "title": "Another image",
932
+ "file": "original_images/another.jpg",
933
+ "width": 1000,
934
+ "height": 1000,
935
+ "created_at": "2020-01-01T12:00:00.000Z"
936
+ }
937
+ },
918
938
  {
919
939
  "model": "wagtailcore.collectionviewrestriction",
920
940
  "pk": 1,
@@ -15,7 +15,7 @@ import wagtail.contrib.table_block.blocks
15
15
  import wagtail.fields
16
16
  import wagtail.images.blocks
17
17
  import wagtail.images.models
18
- import wagtail.models.collections
18
+ import wagtail.models.media
19
19
  import wagtail.search.index
20
20
  import wagtail.test.testapp.models
21
21
 
@@ -1043,7 +1043,7 @@ class Migration(migrations.Migration):
1043
1043
  (
1044
1044
  "collection",
1045
1045
  models.ForeignKey(
1046
- default=wagtail.models.collections.get_root_collection_id,
1046
+ default=wagtail.models.media.get_root_collection_id,
1047
1047
  on_delete=django.db.models.deletion.CASCADE,
1048
1048
  related_name="+",
1049
1049
  to="wagtailcore.collection",
@@ -2244,7 +2244,7 @@ class Migration(migrations.Migration):
2244
2244
  (
2245
2245
  "collection",
2246
2246
  models.ForeignKey(
2247
- default=wagtail.models.collections.get_root_collection_id,
2247
+ default=wagtail.models.media.get_root_collection_id,
2248
2248
  on_delete=django.db.models.deletion.CASCADE,
2249
2249
  related_name="+",
2250
2250
  to="wagtailcore.collection",
@@ -2341,7 +2341,7 @@ class Migration(migrations.Migration):
2341
2341
  (
2342
2342
  "collection",
2343
2343
  models.ForeignKey(
2344
- default=wagtail.models.collections.get_root_collection_id,
2344
+ default=wagtail.models.media.get_root_collection_id,
2345
2345
  on_delete=django.db.models.deletion.CASCADE,
2346
2346
  related_name="+",
2347
2347
  to="wagtailcore.collection",
@@ -2622,7 +2622,7 @@ class Migration(migrations.Migration):
2622
2622
  (
2623
2623
  "collection",
2624
2624
  models.ForeignKey(
2625
- default=wagtail.models.collections.get_root_collection_id,
2625
+ default=wagtail.models.media.get_root_collection_id,
2626
2626
  on_delete=django.db.models.deletion.CASCADE,
2627
2627
  related_name="+",
2628
2628
  to="wagtailcore.collection",
@@ -3891,7 +3891,7 @@ class Migration(migrations.Migration):
3891
3891
  (
3892
3892
  "collection",
3893
3893
  models.ForeignKey(
3894
- default=wagtail.models.collections.get_root_collection_id,
3894
+ default=wagtail.models.media.get_root_collection_id,
3895
3895
  on_delete=django.db.models.deletion.CASCADE,
3896
3896
  related_name="+",
3897
3897
  to="wagtailcore.collection",
@@ -3936,7 +3936,7 @@ class Migration(migrations.Migration):
3936
3936
  (
3937
3937
  "collection",
3938
3938
  models.ForeignKey(
3939
- default=wagtail.models.collections.get_root_collection_id,
3939
+ default=wagtail.models.media.get_root_collection_id,
3940
3940
  on_delete=django.db.models.deletion.CASCADE,
3941
3941
  related_name="+",
3942
3942
  to="wagtailcore.collection",
@@ -4055,7 +4055,7 @@ class Migration(migrations.Migration):
4055
4055
  (
4056
4056
  "collection",
4057
4057
  models.ForeignKey(
4058
- default=wagtail.models.collections.get_root_collection_id,
4058
+ default=wagtail.models.media.get_root_collection_id,
4059
4059
  on_delete=django.db.models.deletion.CASCADE,
4060
4060
  related_name="+",
4061
4061
  to="wagtailcore.collection",
@@ -19,6 +19,7 @@ class Migration(migrations.Migration):
19
19
  null=True,
20
20
  on_delete=django.db.models.deletion.CASCADE,
21
21
  to="tests.fullfeaturedsnippet",
22
+ verbose_name="Chosen snippet",
22
23
  ),
23
24
  ),
24
25
  ]
@@ -0,0 +1,44 @@
1
+ # Generated by Django 4.2.7 on 2024-02-22 09:21
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("tests", "0033_customcopyformpage"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.CreateModel(
13
+ name="CustomPermissionModel",
14
+ fields=[
15
+ (
16
+ "id",
17
+ models.AutoField(
18
+ auto_created=True,
19
+ primary_key=True,
20
+ serialize=False,
21
+ verbose_name="ID",
22
+ ),
23
+ ),
24
+ ("text", models.TextField(default="Tailwag")),
25
+ ],
26
+ options={
27
+ "verbose_name": "ADVANCED permission model",
28
+ "verbose_name_plural": "ADVANCED permission models",
29
+ "permissions": [
30
+ ("can_start_trouble", "Can start trouble"),
31
+ ("cause_chaos", "Cause chaos for advanced permission model"),
32
+ ("change_text", "Change text"),
33
+ ("control", "Manage custom permission model"),
34
+ ],
35
+ "default_permissions": (
36
+ "add",
37
+ "change",
38
+ "delete",
39
+ "view",
40
+ "bulk_update",
41
+ ),
42
+ },
43
+ ),
44
+ ]
@@ -0,0 +1,30 @@
1
+ # Generated by Django 5.0.1 on 2024-03-15 21:20
2
+
3
+ import django.db.models.manager
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("tests", "0034_custompermissionmodel"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.CreateModel(
14
+ name="ModelWithCustomManager",
15
+ fields=[
16
+ (
17
+ "id",
18
+ models.AutoField(
19
+ auto_created=True,
20
+ primary_key=True,
21
+ serialize=False,
22
+ verbose_name="ID",
23
+ ),
24
+ ),
25
+ ],
26
+ managers=[
27
+ ("instances", django.db.models.manager.Manager()),
28
+ ],
29
+ ),
30
+ ]
@@ -0,0 +1,28 @@
1
+ # Generated by Django 5.0.3 on 2024-04-15 22:12
2
+
3
+ import django.db.models.deletion
4
+ import wagtail.blocks
5
+ import wagtail.fields
6
+ from django.db import migrations, models
7
+
8
+
9
+ class Migration(migrations.Migration):
10
+
11
+ dependencies = [
12
+ ('tests', '0035_modelwithcustommanager'),
13
+ ('wagtailcore', '0093_uploadedfile'),
14
+ ]
15
+
16
+ operations = [
17
+ migrations.CreateModel(
18
+ name='ComplexDefaultStreamPage',
19
+ fields=[
20
+ ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
21
+ ('body', wagtail.fields.StreamField([('text', wagtail.blocks.CharBlock()), ('rich_text', wagtail.blocks.RichTextBlock()), ('books', wagtail.blocks.StreamBlock([('title', wagtail.blocks.CharBlock()), ('author', wagtail.blocks.CharBlock())]))], default=[('rich_text', '<p>My <i>lovely</i> books</p>'), ('books', [('title', 'The Great Gatsby'), ('author', 'F. Scott Fitzgerald')])])),
22
+ ],
23
+ options={
24
+ 'abstract': False,
25
+ },
26
+ bases=('wagtailcore.page',),
27
+ ),
28
+ ]
@@ -556,7 +556,7 @@ class FormPage(AbstractEmailForm):
556
556
 
557
557
  # This is redundant (SubmissionsListView is the default view class), but importing
558
558
  # SubmissionsListView in this models.py helps us to confirm that this recipe
559
- # https://docs.wagtail.org/en/stable/reference/contrib/forms/customisation.html#customise-form-submissions-listing-in-wagtail-admin
559
+ # https://docs.wagtail.org/en/stable/reference/contrib/forms/customization.html#customise-form-submissions-listing-in-wagtail-admin
560
560
  # works without triggering circular dependency issues -
561
561
  # see https://github.com/wagtail/wagtail/issues/6265
562
562
  submissions_list_view_class = SubmissionsListView
@@ -1011,6 +1011,17 @@ class AdvertWithTabbedInterface(models.Model):
1011
1011
  register_snippet(AdvertWithTabbedInterface)
1012
1012
 
1013
1013
 
1014
+ class CustomManager(models.Manager):
1015
+ pass
1016
+
1017
+
1018
+ class ModelWithCustomManager(models.Model):
1019
+ instances = CustomManager()
1020
+
1021
+
1022
+ register_snippet(ModelWithCustomManager)
1023
+
1024
+
1014
1025
  # Models with RevisionMixin
1015
1026
  class RevisableModel(RevisionMixin, models.Model):
1016
1027
  text = models.TextField()
@@ -1423,7 +1434,11 @@ class EventPageChooserModel(models.Model):
1423
1434
  class SnippetChooserModel(models.Model):
1424
1435
  advert = models.ForeignKey(Advert, help_text="help text", on_delete=models.CASCADE)
1425
1436
  full_featured = models.ForeignKey(
1426
- FullFeaturedSnippet, on_delete=models.CASCADE, null=True, blank=True
1437
+ FullFeaturedSnippet,
1438
+ on_delete=models.CASCADE,
1439
+ null=True,
1440
+ blank=True,
1441
+ verbose_name="Chosen snippet",
1427
1442
  )
1428
1443
 
1429
1444
  panels = [
@@ -1611,6 +1626,36 @@ class DefaultStreamPage(Page):
1611
1626
  ]
1612
1627
 
1613
1628
 
1629
+ class ComplexDefaultStreamPage(Page):
1630
+ body = StreamField(
1631
+ [
1632
+ ("text", CharBlock()),
1633
+ ("rich_text", RichTextBlock()),
1634
+ (
1635
+ "books",
1636
+ StreamBlock(
1637
+ [
1638
+ ("title", CharBlock()),
1639
+ ("author", CharBlock()),
1640
+ ]
1641
+ ),
1642
+ ),
1643
+ ],
1644
+ default=[
1645
+ ("rich_text", "<p>My <i>lovely</i> books</p>"),
1646
+ (
1647
+ "books",
1648
+ [("title", "The Great Gatsby"), ("author", "F. Scott Fitzgerald")],
1649
+ ),
1650
+ ],
1651
+ )
1652
+
1653
+ content_panels = [
1654
+ FieldPanel("title"),
1655
+ FieldPanel("body"),
1656
+ ]
1657
+
1658
+
1614
1659
  class MTIBasePage(Page):
1615
1660
  is_creatable = False
1616
1661
 
@@ -2256,3 +2301,35 @@ class CustomPermissionTester(PagePermissionTester):
2256
2301
  class CustomPermissionPage(Page):
2257
2302
  def permissions_for_user(self, user):
2258
2303
  return CustomPermissionTester(user, self)
2304
+
2305
+
2306
+ class CustomPermissionModel(models.Model):
2307
+ text = models.TextField(default="Tailwag")
2308
+
2309
+ class Meta:
2310
+ verbose_name = "ADVANCED permission model"
2311
+ verbose_name_plural = "ADVANCED permission models"
2312
+
2313
+ # Django's default_permissions are ("add", "change", "delete", "view").
2314
+ # Django will generate permissions for each of these actions with the
2315
+ # format f"{action}_{model_name}" and the label "Can {action} {verbose_name}".
2316
+ # This means if the action is "bulk_update", the codename will be
2317
+ # "bulk_update_custompermissionmodel" and the label will be
2318
+ # "Can bulk_update ADVANCED permission model".
2319
+ # See https://github.com/django/django/blob/stable/5.0.x/django/contrib/auth/management/__init__.py#L22-L35
2320
+ default_permissions = ("add", "change", "delete", "view", "bulk_update")
2321
+
2322
+ # Permissions with completely custom codenames and labels
2323
+ permissions = [
2324
+ # Starts with can_ and "Can "
2325
+ ("can_start_trouble", "Can start trouble"),
2326
+ # Doesn't start with can_ and "Can "
2327
+ ("cause_chaos", "Cause chaos for advanced permission model"),
2328
+ # Starts with an action similar to a built-in permission "change_"
2329
+ ("change_text", "Change text"),
2330
+ # Without any _ and the label ends with the default verbose_name
2331
+ ("control", "Manage custom permission model"),
2332
+ ]
2333
+
2334
+
2335
+ register_snippet(CustomPermissionModel)
@@ -0,0 +1,10 @@
1
+ {% extends "tests/base.html" %}
2
+
3
+ {% block content %}
4
+ <p>Test only.</p>
5
+ <form action="{{ action_url }}" method="POST">
6
+ {% csrf_token %}
7
+ {{ form.as_p }}
8
+ <input type="submit" value="Continue" class="button" />
9
+ </form>
10
+ {% endblock %}
@@ -0,0 +1,10 @@
1
+ {% extends "tests/base.html" %}
2
+
3
+ {% block content %}
4
+ <p>Test only.</p>
5
+ <form action="{{ action_url }}" method="POST">
6
+ {% csrf_token %}
7
+ {{ form.as_p }}
8
+ <input type="submit" value="Continue" class="button" />
9
+ </form>
10
+ {% endblock %}
@@ -12,14 +12,16 @@ from wagtail.admin import messages
12
12
  from wagtail.admin.auth import user_passes_test
13
13
  from wagtail.admin.filters import WagtailFilterSet
14
14
  from wagtail.admin.panels import FieldPanel
15
- from wagtail.admin.ui.tables import BooleanColumn, UpdatedAtColumn
15
+ from wagtail.admin.ui.tables import BooleanColumn, Column, UpdatedAtColumn
16
16
  from wagtail.admin.views.generic import DeleteView, EditView, IndexView
17
17
  from wagtail.admin.viewsets.base import ViewSet, ViewSetGroup
18
18
  from wagtail.admin.viewsets.chooser import ChooserViewSet
19
19
  from wagtail.admin.viewsets.model import ModelViewSet, ModelViewSetGroup
20
+ from wagtail.admin.viewsets.pages import PageListingViewSet
20
21
  from wagtail.contrib.forms.views import SubmissionsListView
21
22
  from wagtail.test.testapp.models import (
22
23
  Advert,
24
+ EventPage,
23
25
  FeatureCompleteToy,
24
26
  JSONBlockCountsStreamModel,
25
27
  JSONMinMaxCountStreamModel,
@@ -49,7 +51,7 @@ def message_test(request):
49
51
 
50
52
  class CustomSubmissionsListView(SubmissionsListView):
51
53
  paginate_by = 50
52
- ordering = ("submit_time",)
54
+ default_ordering = ("submit_time",)
53
55
  ordering_csv = ("-submit_time",)
54
56
 
55
57
  def get_csv_filename(self):
@@ -295,3 +297,23 @@ animated_advert_chooser_viewset = AnimatedAdvertChooserViewSet(
295
297
  )
296
298
 
297
299
  AdvertChooserWidget = animated_advert_chooser_viewset.widget_class
300
+
301
+
302
+ class EventPageFilterSet(PageListingViewSet.filterset_class):
303
+ class Meta:
304
+ model = EventPage
305
+ fields = ["audience"]
306
+
307
+
308
+ class EventPageListingViewSet(PageListingViewSet):
309
+ model = EventPage
310
+ icon = "calendar"
311
+ menu_label = "Event pages"
312
+ add_to_admin_menu = True
313
+ columns = PageListingViewSet.columns + [
314
+ Column("audience", label="Audience", sort_key="audience"),
315
+ ]
316
+ filterset_class = EventPageFilterSet
317
+
318
+
319
+ event_page_listing_viewset = EventPageListingViewSet("event_pages")
@@ -31,6 +31,7 @@ from wagtail.test.testapp.models import (
31
31
  ModeratedModel,
32
32
  RevisableChildModel,
33
33
  RevisableModel,
34
+ SnippetChooserModel,
34
35
  VariousOnDeleteModel,
35
36
  )
36
37
  from wagtail.test.testapp.views import (
@@ -39,6 +40,7 @@ from wagtail.test.testapp.views import (
39
40
  SearchTestModelViewSet,
40
41
  ToyViewSetGroup,
41
42
  animated_advert_chooser_viewset,
43
+ event_page_listing_viewset,
42
44
  )
43
45
 
44
46
  from .forms import FavouriteColourForm
@@ -384,12 +386,24 @@ class VariousOnDeleteModelViewSet(SnippetViewSet):
384
386
  inspect_view_enabled = True
385
387
 
386
388
 
389
+ class SnippetChooserModelViewSet(SnippetViewSet):
390
+ model = SnippetChooserModel
391
+
392
+ list_display = [
393
+ "__str__",
394
+ "full_featured__text",
395
+ "full_featured__latest_revision__created_at",
396
+ ]
397
+ exclude_form_fields = []
398
+
399
+
387
400
  register_snippet(FullFeaturedSnippet, viewset=FullFeaturedSnippetViewSet)
388
401
  register_snippet(DraftStateModel, viewset=DraftStateModelViewSet)
389
402
  # Works with both classes and instances
390
403
  register_snippet(ModeratedModelViewSet())
391
404
  register_snippet(RevisableViewSetGroup)
392
405
  register_snippet(VariousOnDeleteModelViewSet)
406
+ register_snippet(SnippetChooserModelViewSet)
393
407
 
394
408
 
395
409
  @hooks.register("register_bulk_action")
@@ -404,3 +418,8 @@ class DisableBulkAction(SnippetBulkAction):
404
418
  @hooks.register("register_admin_viewset")
405
419
  def register_animated_advert_chooser_viewset():
406
420
  return animated_advert_chooser_viewset
421
+
422
+
423
+ @hooks.register("register_admin_viewset")
424
+ def register_event_page_listing_viewset():
425
+ return event_page_listing_viewset
@@ -9,8 +9,8 @@ from django.test.testcases import assert_and_parse_html
9
9
 
10
10
  class WagtailTestUtils:
11
11
  @staticmethod
12
- def get_soup(markup: Union[str, bytes], parser="html.parser") -> BeautifulSoup:
13
- return BeautifulSoup(markup, parser)
12
+ def get_soup(markup: Union[str, bytes]) -> BeautifulSoup:
13
+ return BeautifulSoup(markup, "html.parser")
14
14
 
15
15
  @staticmethod
16
16
  def create_test_user():