wagtail 6.2.2__py3-none-any.whl → 6.3rc2__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.
- wagtail/__init__.py +1 -1
- wagtail/actions/copy_for_translation.py +6 -0
- wagtail/actions/publish_revision.py +3 -3
- wagtail/admin/action_menu.py +5 -3
- wagtail/admin/forms/account.py +1 -1
- wagtail/admin/icons.py +2 -6
- wagtail/admin/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/cy/LC_MESSAGES/django.po +32 -0
- wagtail/admin/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/dv/LC_MESSAGES/django.po +28 -0
- wagtail/admin/locale/en/LC_MESSAGES/django.po +451 -485
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +7 -7
- wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/django.po +150 -0
- wagtail/admin/locale/sl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/djangojs.po +9 -2
- wagtail/admin/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ug/LC_MESSAGES/django.po +3250 -196
- wagtail/admin/localization.py +12 -2
- wagtail/admin/panels/model_utils.py +1 -1
- wagtail/admin/site_summary.py +0 -2
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
- wagtail/admin/static/wagtailadmin/images/email-header.jpg +0 -0
- wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +12 -0
- wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/staticfiles.py +6 -4
- wagtail/admin/templates/wagtailadmin/account/account.html +42 -59
- wagtail/admin/templates/wagtailadmin/admin_base.html +0 -28
- wagtail/admin/templates/wagtailadmin/bulk_actions/footer.html +1 -1
- wagtail/admin/templates/wagtailadmin/chooser/_search_results.html +7 -5
- wagtail/admin/templates/wagtailadmin/chooser/tables/page_navigate_to_children_cell.html +1 -1
- wagtail/admin/templates/wagtailadmin/generic/chooser/results.html +7 -5
- wagtail/admin/templates/wagtailadmin/generic/edit.html +0 -8
- wagtail/admin/templates/wagtailadmin/generic/form.html +60 -17
- wagtail/admin/templates/wagtailadmin/generic/index.html +17 -0
- wagtail/admin/templates/wagtailadmin/generic/index_results.html +9 -35
- wagtail/admin/templates/wagtailadmin/generic/inspect.html +2 -21
- wagtail/admin/templates/wagtailadmin/generic/listing.html +11 -17
- wagtail/admin/templates/wagtailadmin/generic/listing_results.html +19 -1
- wagtail/admin/templates/wagtailadmin/home/account_summary.html +26 -0
- wagtail/admin/templates/wagtailadmin/home/locked_pages.html +28 -18
- wagtail/admin/templates/wagtailadmin/home/recent_edits.html +28 -17
- wagtail/admin/templates/wagtailadmin/home/site_summary_pages.html +2 -2
- wagtail/admin/templates/wagtailadmin/home/upgrade_notification.html +35 -13
- wagtail/admin/templates/wagtailadmin/home/user_objects_in_workflow_moderation.html +28 -18
- wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +43 -32
- wagtail/admin/templates/wagtailadmin/home.html +22 -5
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -1
- wagtail/admin/templates/wagtailadmin/pages/action_menu/menu.html +1 -11
- wagtail/admin/templates/wagtailadmin/pages/action_menu/menu_item.html +1 -6
- wagtail/admin/templates/wagtailadmin/pages/action_menu/page_locked.html +1 -1
- wagtail/admin/templates/wagtailadmin/pages/action_menu/publish.html +1 -1
- wagtail/admin/templates/wagtailadmin/pages/action_menu/save_draft.html +1 -1
- wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_delete.html +12 -6
- wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_move.html +12 -7
- wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_publish.html +17 -11
- wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_unpublish.html +15 -9
- wagtail/admin/templates/wagtailadmin/pages/confirm_delete.html +9 -9
- wagtail/admin/templates/wagtailadmin/pages/confirm_move.html +2 -2
- wagtail/admin/templates/wagtailadmin/pages/confirm_unpublish.html +4 -4
- wagtail/admin/templates/wagtailadmin/pages/create.html +15 -34
- wagtail/admin/templates/wagtailadmin/pages/edit.html +15 -30
- wagtail/admin/templates/wagtailadmin/pages/explorable_index.html +6 -0
- wagtail/admin/templates/wagtailadmin/pages/explorable_index_results.html +60 -0
- wagtail/admin/templates/wagtailadmin/pages/index.html +1 -36
- wagtail/admin/templates/wagtailadmin/pages/index_results.html +2 -50
- wagtail/admin/templates/wagtailadmin/pages/listing/_locked_indicator.html +1 -1
- wagtail/admin/templates/wagtailadmin/pages/listing/_ordering_cell.html +1 -1
- wagtail/admin/templates/wagtailadmin/pages/listing/_page_header_buttons.html +1 -1
- wagtail/admin/templates/wagtailadmin/pages/listing/_page_title_column_header.html +3 -3
- wagtail/admin/templates/wagtailadmin/pages/listing/_pagination.html +1 -1
- wagtail/admin/templates/wagtailadmin/pages/listing.html +24 -0
- wagtail/admin/templates/wagtailadmin/pages/search.html +1 -20
- wagtail/admin/templates/wagtailadmin/pages/search_results.html +27 -25
- wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html +0 -1
- wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_report.html +2 -2
- wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +6 -6
- wagtail/admin/templates/wagtailadmin/reports/workflow_tasks_results.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/action_menu/menu.html +14 -0
- wagtail/admin/templates/wagtailadmin/shared/action_menu/menu_item.html +6 -0
- wagtail/admin/templates/wagtailadmin/shared/avatar.html +13 -3
- wagtail/admin/templates/wagtailadmin/shared/header.html +0 -5
- wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +4 -1
- wagtail/admin/templates/wagtailadmin/shared/pagination_nav.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/locale.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/usage.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +94 -52
- wagtail/admin/templates/wagtailadmin/{pages/_unsaved_changes_warning.html → shared/unsaved_changes_warning.html} +4 -4
- wagtail/admin/templates/wagtailadmin/shared/usage_summary.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/workflow_history/detail.html +1 -7
- wagtail/admin/templates/wagtailadmin/shared/workflow_history/listing.html +1 -0
- wagtail/admin/templates/wagtailadmin/shared/workflow_history/{list.html → listing_results.html} +33 -35
- wagtail/admin/templates/wagtailadmin/tables/references_cell.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/create.html +11 -36
- wagtail/admin/templates/wagtailadmin/workflows/create_task.html +0 -38
- wagtail/admin/templates/wagtailadmin/workflows/edit.html +44 -74
- wagtail/admin/templates/wagtailadmin/workflows/edit_task.html +27 -66
- wagtail/admin/templates/wagtailadmin/workflows/includes/task_usage_cell.html +4 -2
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_tasks_cell.html +4 -4
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_used_by_cell.html +15 -11
- wagtail/admin/templates/wagtailadmin/workflows/task_chooser/includes/results.html +7 -5
- wagtail/admin/templatetags/wagtailadmin_tags.py +51 -22
- wagtail/admin/tests/pages/test_content_type_use_view.py +82 -2
- wagtail/admin/tests/pages/test_edit_page.py +70 -0
- wagtail/admin/tests/pages/test_explorer_view.py +65 -4
- wagtail/admin/tests/pages/test_page_search.py +8 -7
- wagtail/admin/tests/pages/test_page_usage.py +3 -1
- wagtail/admin/tests/pages/test_preview.py +208 -63
- wagtail/admin/tests/pages/test_reorder_page.py +91 -1
- wagtail/admin/tests/pages/test_view_draft.py +32 -1
- wagtail/admin/tests/pages/test_workflow_history.py +288 -7
- wagtail/admin/tests/test_account_management.py +23 -3
- wagtail/admin/tests/test_audit_log.py +24 -2
- wagtail/admin/tests/test_collections_views.py +17 -5
- wagtail/admin/tests/test_dashboard.py +1 -1
- wagtail/admin/tests/test_edit_handlers.py +3 -2
- wagtail/admin/tests/test_icon_sprite.py +4 -0
- wagtail/admin/tests/test_privacy.py +5 -19
- wagtail/admin/tests/test_reports_views.py +1 -1
- wagtail/admin/tests/test_site_summary.py +3 -3
- wagtail/admin/tests/test_templatetags.py +27 -3
- wagtail/admin/tests/test_upgrade_notification.py +71 -18
- wagtail/admin/tests/test_views.py +2 -2
- wagtail/admin/tests/test_views_generic.py +13 -0
- wagtail/admin/tests/test_widgets.py +3 -3
- wagtail/admin/tests/test_workflows.py +172 -27
- wagtail/admin/tests/tests.py +1 -1
- wagtail/admin/tests/viewsets/test_model_viewset.py +55 -3
- wagtail/admin/ui/side_panels.py +19 -0
- wagtail/admin/ui/sidebar.py +4 -3
- wagtail/admin/ui/tables/__init__.py +14 -1
- wagtail/admin/ui/tables/pages.py +6 -1
- wagtail/admin/urls/pages.py +10 -1
- wagtail/admin/urls/workflows.py +6 -1
- wagtail/admin/views/account.py +5 -1
- wagtail/admin/views/collections.py +0 -2
- wagtail/admin/views/generic/base.py +118 -1
- wagtail/admin/views/generic/history.py +158 -26
- wagtail/admin/views/generic/models.py +113 -99
- wagtail/admin/views/home.py +24 -9
- wagtail/admin/views/page_privacy.py +54 -30
- wagtail/admin/views/pages/history.py +11 -4
- wagtail/admin/views/pages/listing.py +76 -89
- wagtail/admin/views/pages/preview.py +1 -1
- wagtail/admin/views/pages/search.py +27 -71
- wagtail/admin/views/pages/usage.py +63 -24
- wagtail/admin/views/pages/utils.py +4 -3
- wagtail/admin/views/reports/base.py +0 -6
- wagtail/admin/views/workflows.py +67 -25
- wagtail/admin/viewsets/model.py +4 -3
- wagtail/admin/widgets/chooser.py +2 -1
- wagtail/api/v2/tests/test_pages.py +15 -2
- wagtail/blocks/field_block.py +15 -3
- wagtail/blocks/static_block.py +3 -0
- wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.po +29 -1
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +15 -11
- wagtail/contrib/forms/templates/wagtailforms/confirm_delete.html +1 -0
- wagtail/contrib/forms/templates/wagtailforms/index.html +1 -1
- wagtail/contrib/forms/templates/wagtailforms/index_results.html +1 -1
- wagtail/contrib/forms/templates/wagtailforms/list_submissions.html +2 -1
- wagtail/contrib/forms/templates/wagtailforms/panels/form_responses_panel.html +2 -2
- wagtail/contrib/forms/tests/test_views.py +234 -35
- wagtail/contrib/forms/utils.py +8 -14
- wagtail/contrib/forms/views.py +72 -27
- wagtail/contrib/frontend_cache/backends/azure.py +1 -1
- wagtail/contrib/frontend_cache/backends/cloudfront.py +2 -2
- wagtail/contrib/frontend_cache/backends/dummy.py +11 -0
- wagtail/contrib/frontend_cache/tests.py +31 -37
- wagtail/contrib/frontend_cache/utils.py +12 -5
- wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.po +16 -1
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +20 -24
- wagtail/contrib/redirects/models.py +16 -1
- wagtail/contrib/redirects/signal_handlers.py +18 -3
- wagtail/contrib/redirects/templates/wagtailredirects/add.html +5 -16
- wagtail/contrib/redirects/templates/wagtailredirects/import_summary.html +1 -1
- wagtail/contrib/redirects/tests/test_redirects.py +49 -6
- wagtail/contrib/redirects/tests/test_signal_handlers.py +42 -1
- wagtail/contrib/redirects/views.py +27 -3
- wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.po +60 -1
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +12 -18
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/add.html +5 -8
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/edit.html +15 -10
- wagtail/contrib/search_promotions/tests.py +13 -2
- wagtail/contrib/search_promotions/views.py +15 -3
- wagtail/contrib/settings/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/cy/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +2 -10
- wagtail/contrib/settings/templates/wagtailsettings/edit.html +12 -45
- wagtail/contrib/simple_translation/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/simple_translation/locale/cy/LC_MESSAGES/django.po +13 -1
- wagtail/contrib/simple_translation/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/simple_translation/locale/dv/LC_MESSAGES/django.po +3 -0
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +4 -4
- wagtail/contrib/simple_translation/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/simple_translation/locale/sl/LC_MESSAGES/django.po +5 -2
- wagtail/contrib/simple_translation/tests/test_views.py +51 -0
- wagtail/contrib/simple_translation/wagtail_hooks.py +16 -11
- wagtail/contrib/styleguide/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/styleguide/locale/cy/LC_MESSAGES/django.po +5 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/cy/LC_MESSAGES/django.po +27 -1
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/blocks.py +25 -0
- wagtail/contrib/typed_table_block/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/cy/LC_MESSAGES/django.po +12 -1
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/contrib/typed_table_block/tests.py +24 -1
- wagtail/coreutils.py +5 -11
- wagtail/documents/admin_urls.py +2 -2
- wagtail/documents/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/cy/LC_MESSAGES/django.po +10 -0
- wagtail/documents/locale/en/LC_MESSAGES/django.po +61 -76
- wagtail/documents/migrations/0014_alter_document_file_size.py +18 -0
- wagtail/documents/models.py +1 -1
- wagtail/documents/rich_text/__init__.py +1 -3
- wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
- wagtail/documents/templates/wagtaildocs/bulk_actions/confirm_bulk_add_tags.html +5 -1
- wagtail/documents/templates/wagtaildocs/bulk_actions/confirm_bulk_add_to_collection.html +5 -1
- wagtail/documents/templates/wagtaildocs/bulk_actions/confirm_bulk_delete.html +11 -5
- wagtail/documents/templates/wagtaildocs/documents/add.html +13 -41
- wagtail/documents/templates/wagtaildocs/documents/edit.html +28 -56
- wagtail/documents/templates/wagtaildocs/documents/index.html +1 -4
- wagtail/documents/templates/wagtaildocs/homepage/site_summary_documents.html +2 -2
- wagtail/documents/templates/wagtaildocs/multiple/add.html +36 -41
- wagtail/documents/tests/test_admin_views.py +64 -6
- wagtail/documents/tests/test_site_summary.py +3 -3
- wagtail/documents/views/documents.py +103 -113
- wagtail/documents/views/multiple.py +19 -1
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/oembed_providers.py +9 -19
- wagtail/fields.py +43 -27
- wagtail/images/admin_urls.py +2 -2
- wagtail/images/blocks.py +230 -2
- wagtail/images/fields.py +17 -29
- wagtail/images/image_operations.py +1 -1
- wagtail/images/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/cy/LC_MESSAGES/django.po +128 -1
- wagtail/images/locale/en/LC_MESSAGES/django.po +119 -129
- wagtail/images/migrations/0025_alter_image_file_alter_rendition_file.py +36 -43
- wagtail/images/migrations/0027_image_description.py +20 -0
- wagtail/images/models.py +120 -45
- wagtail/images/rich_text/__init__.py +1 -3
- wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
- wagtail/images/static/wagtailimages/js/image-block.js +1 -0
- wagtail/images/templates/wagtailimages/bulk_actions/confirm_bulk_add_tags.html +5 -1
- wagtail/images/templates/wagtailimages/bulk_actions/confirm_bulk_add_to_collection.html +5 -1
- wagtail/images/templates/wagtailimages/bulk_actions/confirm_bulk_delete.html +11 -5
- wagtail/images/templates/wagtailimages/chooser/results.html +2 -2
- wagtail/images/templates/wagtailimages/homepage/site_summary_images.html +2 -2
- wagtail/images/templates/wagtailimages/images/_file_field.html +2 -2
- wagtail/images/templates/wagtailimages/images/add.html +13 -31
- wagtail/images/templates/wagtailimages/images/edit.html +53 -82
- wagtail/images/templates/wagtailimages/images/index.html +1 -4
- wagtail/images/templates/wagtailimages/images/url_generator.html +1 -1
- wagtail/images/templates/wagtailimages/multiple/add.html +40 -47
- wagtail/images/templates/wagtailimages/widgets/image.html +5 -0
- wagtail/images/templates/wagtailimages/widgets/image_chooser.html +1 -1
- wagtail/images/tests/test_admin_views.py +70 -10
- wagtail/images/tests/test_blocks.py +367 -1
- wagtail/images/tests/test_image_operations.py +23 -0
- wagtail/images/tests/test_models.py +20 -0
- wagtail/images/tests/test_signal_handlers.py +99 -95
- wagtail/images/tests/test_site_summary.py +3 -3
- wagtail/images/tests/test_templatetags.py +11 -7
- wagtail/images/tests/tests.py +4 -0
- wagtail/images/views/images.py +103 -104
- wagtail/images/views/multiple.py +17 -1
- wagtail/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/cy/LC_MESSAGES/django.po +3 -0
- wagtail/locale/en/LC_MESSAGES/django.po +137 -125
- wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sl/LC_MESSAGES/django.po +3 -0
- wagtail/locales/locale/en/LC_MESSAGES/django.po +8 -8
- wagtail/locales/views.py +4 -1
- wagtail/migrations/0089_log_entry_data_json_null_to_object.py +1 -7
- wagtail/models/__init__.py +122 -14
- wagtail/models/audit_log.py +1 -3
- wagtail/models/i18n.py +1 -2
- wagtail/project_template/Dockerfile +3 -3
- wagtail/project_template/requirements.txt +2 -2
- wagtail/query.py +17 -4
- wagtail/rich_text/__init__.py +2 -3
- wagtail/rich_text/pages.py +2 -4
- wagtail/rich_text/rewriters.py +2 -2
- wagtail/search/backends/database/mysql/query.py +3 -3
- wagtail/search/backends/database/sqlite/query.py +6 -6
- wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/en/LC_MESSAGES/django.po +6 -6
- wagtail/sites/views.py +0 -1
- wagtail/snippets/action_menu.py +14 -4
- wagtail/snippets/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/cy/LC_MESSAGES/django.po +73 -1
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +27 -33
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
- wagtail/snippets/templates/wagtailsnippets/bulk_actions/confirm_bulk_delete.html +5 -3
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/locked.html +1 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu.html +1 -11
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu_item.html +1 -6
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/publish.html +1 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/save.html +1 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/create.html +1 -18
- wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +1 -14
- wagtail/snippets/templates/wagtailsnippets/snippets/index.html +2 -5
- wagtail/snippets/tests/test_preview.py +193 -61
- wagtail/snippets/tests/test_snippets.py +247 -38
- wagtail/snippets/tests/test_usage.py +5 -0
- wagtail/snippets/tests/test_viewset.py +25 -9
- wagtail/snippets/tests/test_workflows.py +232 -19
- wagtail/snippets/views/snippets.py +1 -10
- wagtail/test/numberformat.py +104 -0
- wagtail/test/settings.py +10 -0
- wagtail/test/settings_ui.py +2 -0
- wagtail/test/testapp/migrations/0010_alter_customimage_file_and_more.py +71 -78
- wagtail/test/testapp/migrations/0040_nocreatablesubpagetypespage_nosubpagetypespage.py +54 -0
- wagtail/test/testapp/migrations/0041_alter_jsonstreammodel_options.py +17 -0
- wagtail/test/testapp/migrations/0042_alter_customdocument_file_size_and_more.py +28 -0
- wagtail/test/testapp/migrations/0043_customimage_description.py +41 -0
- wagtail/test/testapp/migrations/0044_custompreviewsizesmodel_custompreviewsizespage.py +52 -0
- wagtail/test/testapp/migrations/0045_alter_streampage_body.py +52 -0
- wagtail/test/testapp/models.py +62 -4
- wagtail/test/testapp/rich_text.py +2 -2
- wagtail/test/testapp/templates/tests/form_page_landing.html +2 -1
- wagtail/test/testapp/urls.py +5 -0
- wagtail/test/testapp/views.py +5 -0
- wagtail/test/utils/page_tests.py +5 -5
- wagtail/test/utils/template_tests.py +2 -2
- wagtail/tests/test_blocks.py +15 -0
- wagtail/tests/test_page_permissions.py +109 -0
- wagtail/tests/test_revision_model.py +27 -0
- wagtail/tests/test_signals.py +21 -2
- wagtail/tests/test_tests.py +30 -0
- wagtail/users/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/cy/LC_MESSAGES/django.po +118 -1
- wagtail/users/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/dv/LC_MESSAGES/django.po +3 -0
- wagtail/users/locale/en/LC_MESSAGES/django.po +89 -113
- wagtail/users/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/sl/LC_MESSAGES/django.po +3 -0
- wagtail/users/migrations/0014_userprofile_contrast.py +23 -0
- wagtail/users/models.py +11 -0
- wagtail/users/templates/wagtailusers/bulk_actions/confirm_bulk_assign_role.html +5 -1
- wagtail/users/templates/wagtailusers/bulk_actions/confirm_bulk_delete.html +5 -1
- wagtail/users/templates/wagtailusers/bulk_actions/confirm_bulk_set_active_state.html +5 -1
- wagtail/users/templates/wagtailusers/groups/create.html +19 -17
- wagtail/users/templates/wagtailusers/groups/edit.html +2 -40
- wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +1 -62
- wagtail/users/templates/wagtailusers/groups/includes/page_permissions_formset.html +0 -1
- wagtail/users/templates/wagtailusers/users/create.html +46 -50
- wagtail/users/templates/wagtailusers/users/edit.html +45 -62
- wagtail/users/templates/wagtailusers/users/index.html +1 -4
- wagtail/users/templatetags/wagtailusers_tags.py +1 -5
- wagtail/users/tests/test_admin_views.py +85 -66
- wagtail/users/views/groups.py +4 -1
- wagtail/users/views/users.py +2 -0
- {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/METADATA +6 -6
- {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/RECORD +378 -367
- wagtail/admin/static/wagtailadmin/js/preview-panel.js +0 -2
- wagtail/admin/static/wagtailadmin/js/preview-panel.js.LICENSE.txt +0 -11
- wagtail/admin/templates/wagtailadmin/generic/history_results.html +0 -1
- wagtail/admin/templates/wagtailadmin/page_privacy/ancestor_privacy.html +0 -3
- wagtail/admin/templates/wagtailadmin/pages/usage_results.html +0 -6
- wagtail/admin/templates/wagtailadmin/shared/workflow_history/index.html +0 -17
- wagtail/admin/templates/wagtailadmin/shared/workflow_history/results.html +0 -17
- wagtail/admin/templates/wagtailadmin/workflows/usage.html +0 -44
- {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/LICENSE +0 -0
- {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/WHEEL +0 -0
- {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/entry_points.txt +0 -0
- {wagtail-6.2.2.dist-info → wagtail-6.3rc2.dist-info}/top_level.txt +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
1
2
|
from datetime import timedelta
|
|
2
3
|
|
|
3
4
|
import django_filters
|
|
4
5
|
from django.contrib.admin.utils import quote
|
|
5
|
-
from django.core.paginator import Paginator
|
|
6
6
|
from django.forms import CheckboxSelectMultiple
|
|
7
7
|
from django.shortcuts import get_object_or_404
|
|
8
8
|
from django.urls import reverse
|
|
@@ -165,6 +165,7 @@ class ActionColumn(Column):
|
|
|
165
165
|
|
|
166
166
|
if (
|
|
167
167
|
(url_name := self.url_names.get("revisions_unschedule"))
|
|
168
|
+
and instance.revision
|
|
168
169
|
and instance.revision.approved_go_live_at
|
|
169
170
|
and self.user_can_unschedule
|
|
170
171
|
):
|
|
@@ -198,9 +199,7 @@ class LogEntryUserColumn(UserColumn):
|
|
|
198
199
|
class HistoryView(PermissionCheckedMixin, BaseObjectMixin, BaseListingView):
|
|
199
200
|
any_permission_required = ["add", "change", "delete"]
|
|
200
201
|
page_title = gettext_lazy("History")
|
|
201
|
-
results_template_name = "wagtailadmin/generic/history_results.html"
|
|
202
202
|
header_icon = "history"
|
|
203
|
-
is_searchable = False
|
|
204
203
|
paginate_by = 20
|
|
205
204
|
filterset_class = HistoryFilterSet
|
|
206
205
|
history_url_name = None
|
|
@@ -298,10 +297,13 @@ class HistoryView(PermissionCheckedMixin, BaseObjectMixin, BaseListingView):
|
|
|
298
297
|
def user_can_unschedule(self):
|
|
299
298
|
return self.user_has_permission("publish")
|
|
300
299
|
|
|
300
|
+
@cached_property
|
|
301
|
+
def verbose_name_plural(self):
|
|
302
|
+
return BaseLogEntry._meta.verbose_name_plural
|
|
303
|
+
|
|
301
304
|
def get_context_data(self, *args, object_list=None, **kwargs):
|
|
302
305
|
context = super().get_context_data(*args, object_list=object_list, **kwargs)
|
|
303
306
|
context["object"] = self.object
|
|
304
|
-
context["model_opts"] = BaseLogEntry._meta
|
|
305
307
|
return context
|
|
306
308
|
|
|
307
309
|
def get_base_queryset(self):
|
|
@@ -324,27 +326,77 @@ class HistoryView(PermissionCheckedMixin, BaseObjectMixin, BaseListingView):
|
|
|
324
326
|
return kwargs
|
|
325
327
|
|
|
326
328
|
|
|
327
|
-
class WorkflowHistoryView(BaseObjectMixin,
|
|
328
|
-
template_name = "wagtailadmin/shared/workflow_history/
|
|
329
|
-
|
|
330
|
-
|
|
329
|
+
class WorkflowHistoryView(BaseObjectMixin, BaseListingView):
|
|
330
|
+
template_name = "wagtailadmin/shared/workflow_history/listing.html"
|
|
331
|
+
results_template_name = "wagtailadmin/shared/workflow_history/listing_results.html"
|
|
332
|
+
paginate_by = 20
|
|
333
|
+
index_url_name = None
|
|
334
|
+
edit_url_name = None
|
|
331
335
|
workflow_history_detail_url_name = None
|
|
336
|
+
page_title = gettext_lazy("Workflow history")
|
|
337
|
+
context_object_name = "workflow_states"
|
|
332
338
|
|
|
333
339
|
@cached_property
|
|
334
|
-
def
|
|
335
|
-
|
|
340
|
+
def index_url(self):
|
|
341
|
+
if self.index_url_name:
|
|
342
|
+
return reverse(self.index_url_name)
|
|
336
343
|
|
|
337
|
-
|
|
338
|
-
|
|
344
|
+
@cached_property
|
|
345
|
+
def edit_url(self):
|
|
346
|
+
if self.edit_url_name:
|
|
347
|
+
return reverse(self.edit_url_name, args=(quote(self.object.pk),))
|
|
339
348
|
|
|
340
|
-
|
|
341
|
-
|
|
349
|
+
@cached_property
|
|
350
|
+
def header_buttons(self):
|
|
351
|
+
buttons = []
|
|
352
|
+
if self.edit_url:
|
|
353
|
+
buttons.append(
|
|
354
|
+
HeaderButton(gettext("Edit"), url=self.edit_url, icon_name="edit")
|
|
355
|
+
)
|
|
356
|
+
return buttons
|
|
357
|
+
|
|
358
|
+
def get_page_subtitle(self):
|
|
359
|
+
return get_latest_str(self.object)
|
|
342
360
|
|
|
361
|
+
def get_breadcrumbs_items(self):
|
|
362
|
+
items = []
|
|
363
|
+
if self.index_url:
|
|
364
|
+
items.append(
|
|
365
|
+
{
|
|
366
|
+
"url": self.index_url,
|
|
367
|
+
"label": capfirst(self.model._meta.verbose_name_plural),
|
|
368
|
+
}
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
if self.edit_url:
|
|
372
|
+
items.append(
|
|
373
|
+
{
|
|
374
|
+
"url": self.edit_url,
|
|
375
|
+
"label": self.get_page_subtitle(),
|
|
376
|
+
}
|
|
377
|
+
)
|
|
378
|
+
items.append(
|
|
379
|
+
{
|
|
380
|
+
"url": "",
|
|
381
|
+
"label": self.get_page_title(),
|
|
382
|
+
"sublabel": self.get_page_subtitle(),
|
|
383
|
+
}
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
return self.breadcrumbs_items + items
|
|
387
|
+
|
|
388
|
+
def get_base_queryset(self):
|
|
389
|
+
return (
|
|
390
|
+
WorkflowState.objects.for_instance(self.object)
|
|
391
|
+
.select_related("workflow", "requested_by")
|
|
392
|
+
.order_by("-created_at")
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
def get_context_data(self, **kwargs):
|
|
396
|
+
context = super().get_context_data(**kwargs)
|
|
343
397
|
context.update(
|
|
344
398
|
{
|
|
345
399
|
"object": self.object,
|
|
346
|
-
"workflow_states": workflow_states,
|
|
347
|
-
"workflow_history_url_name": self.workflow_history_url_name,
|
|
348
400
|
"workflow_history_detail_url_name": self.workflow_history_detail_url_name,
|
|
349
401
|
"model_opts": self.object._meta,
|
|
350
402
|
}
|
|
@@ -356,36 +408,105 @@ class WorkflowHistoryDetailView(
|
|
|
356
408
|
BaseObjectMixin, WagtailAdminTemplateMixin, TemplateView
|
|
357
409
|
):
|
|
358
410
|
template_name = "wagtailadmin/shared/workflow_history/detail.html"
|
|
411
|
+
index_url_name = None
|
|
412
|
+
edit_url_name = None
|
|
359
413
|
workflow_state_url_kwarg = "workflow_state_id"
|
|
360
414
|
workflow_history_url_name = None
|
|
361
415
|
page_title = gettext_lazy("Workflow progress")
|
|
362
416
|
header_icon = "list-ul"
|
|
363
417
|
object_icon = "doc-empty-inverse"
|
|
418
|
+
_show_breadcrumbs = True
|
|
419
|
+
|
|
420
|
+
@cached_property
|
|
421
|
+
def index_url(self):
|
|
422
|
+
if self.index_url_name:
|
|
423
|
+
return reverse(self.index_url_name)
|
|
424
|
+
|
|
425
|
+
@cached_property
|
|
426
|
+
def edit_url(self):
|
|
427
|
+
if self.edit_url_name:
|
|
428
|
+
return reverse(self.edit_url_name, args=(quote(self.object.pk),))
|
|
429
|
+
|
|
430
|
+
@cached_property
|
|
431
|
+
def workflow_history_url(self):
|
|
432
|
+
if self.workflow_history_url_name:
|
|
433
|
+
return reverse(
|
|
434
|
+
self.workflow_history_url_name, args=(quote(self.object.pk),)
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
def get_breadcrumbs_items(self):
|
|
438
|
+
items = []
|
|
439
|
+
if self.index_url:
|
|
440
|
+
items.append(
|
|
441
|
+
{
|
|
442
|
+
"url": self.index_url,
|
|
443
|
+
"label": capfirst(self.model._meta.verbose_name_plural),
|
|
444
|
+
}
|
|
445
|
+
)
|
|
446
|
+
if self.edit_url:
|
|
447
|
+
items.append(
|
|
448
|
+
{
|
|
449
|
+
"url": self.edit_url,
|
|
450
|
+
"label": self.get_page_subtitle(),
|
|
451
|
+
}
|
|
452
|
+
)
|
|
453
|
+
if self.workflow_history_url:
|
|
454
|
+
items.append(
|
|
455
|
+
{
|
|
456
|
+
"url": self.workflow_history_url,
|
|
457
|
+
"label": gettext("Workflow history"),
|
|
458
|
+
}
|
|
459
|
+
)
|
|
460
|
+
items.append(
|
|
461
|
+
{
|
|
462
|
+
"url": "",
|
|
463
|
+
"label": self.get_page_title(),
|
|
464
|
+
"sublabel": self.get_page_subtitle(),
|
|
465
|
+
}
|
|
466
|
+
)
|
|
467
|
+
return self.breadcrumbs_items + items
|
|
468
|
+
|
|
469
|
+
def get_page_subtitle(self):
|
|
470
|
+
return get_latest_str(self.object)
|
|
471
|
+
|
|
472
|
+
@cached_property
|
|
473
|
+
def header_buttons(self):
|
|
474
|
+
buttons = []
|
|
475
|
+
if self.edit_url:
|
|
476
|
+
buttons.append(
|
|
477
|
+
HeaderButton(
|
|
478
|
+
gettext("Edit / Review"),
|
|
479
|
+
url=self.edit_url,
|
|
480
|
+
icon_name="edit",
|
|
481
|
+
)
|
|
482
|
+
)
|
|
483
|
+
return buttons
|
|
364
484
|
|
|
365
485
|
@cached_property
|
|
366
486
|
def workflow_state(self):
|
|
367
487
|
return get_object_or_404(
|
|
368
|
-
WorkflowState.objects.for_instance(self.object)
|
|
369
|
-
|
|
370
|
-
)
|
|
488
|
+
WorkflowState.objects.for_instance(self.object)
|
|
489
|
+
.filter(id=self.kwargs[self.workflow_state_url_kwarg])
|
|
490
|
+
.select_related("requested_by", "requested_by__wagtail_userprofile")
|
|
371
491
|
)
|
|
372
492
|
|
|
373
493
|
@cached_property
|
|
374
494
|
def revisions(self):
|
|
375
495
|
"""
|
|
376
|
-
Get QuerySet of all revisions that
|
|
377
|
-
It's possible that
|
|
496
|
+
Get QuerySet of all revisions that caused a task state change during this
|
|
497
|
+
workflow state. It's possible that a task is rejected and then resubmitted,
|
|
378
498
|
so some tasks may be repeated. All tasks that have been completed no matter
|
|
379
499
|
what revision needs to be displayed on this page.
|
|
380
500
|
"""
|
|
381
501
|
return (
|
|
382
502
|
Revision.objects.for_instance(self.object)
|
|
503
|
+
.select_related("user")
|
|
383
504
|
.filter(
|
|
384
505
|
id__in=TaskState.objects.filter(
|
|
385
506
|
workflow_state=self.workflow_state
|
|
386
507
|
).values_list("revision_id", flat=True),
|
|
387
508
|
)
|
|
388
|
-
.order_by("
|
|
509
|
+
.order_by("created_at")
|
|
389
510
|
)
|
|
390
511
|
|
|
391
512
|
@cached_property
|
|
@@ -395,14 +516,25 @@ class WorkflowHistoryDetailView(
|
|
|
395
516
|
@cached_property
|
|
396
517
|
def task_states_by_revision(self):
|
|
397
518
|
"""Get QuerySet of tasks completed for each revision."""
|
|
519
|
+
# Fetch task states for the revisions in one query instead of one query per revision
|
|
520
|
+
task_states = (
|
|
521
|
+
TaskState.objects.filter(
|
|
522
|
+
workflow_state=self.workflow_state,
|
|
523
|
+
revision_id__in=[revision.pk for revision in self.revisions],
|
|
524
|
+
)
|
|
525
|
+
.prefetch_related("task", "finished_by")
|
|
526
|
+
.specific()
|
|
527
|
+
)
|
|
528
|
+
task_states_by_revision_id = defaultdict(list)
|
|
529
|
+
for task_state in task_states:
|
|
530
|
+
task_states_by_revision_id[task_state.revision_id].append(task_state)
|
|
531
|
+
|
|
398
532
|
task_states_by_revision_task = [
|
|
399
533
|
(
|
|
400
534
|
revision,
|
|
401
535
|
{
|
|
402
536
|
task_state.task: task_state
|
|
403
|
-
for task_state in
|
|
404
|
-
workflow_state=self.workflow_state, revision=revision
|
|
405
|
-
).specific()
|
|
537
|
+
for task_state in task_states_by_revision_id[revision.pk]
|
|
406
538
|
},
|
|
407
539
|
)
|
|
408
540
|
for revision in self.revisions
|
|
@@ -422,6 +554,7 @@ class WorkflowHistoryDetailView(
|
|
|
422
554
|
"""Generate timeline."""
|
|
423
555
|
completed_task_states = (
|
|
424
556
|
TaskState.objects.filter(workflow_state=self.workflow_state)
|
|
557
|
+
.select_related("finished_by", "task")
|
|
425
558
|
.exclude(finished_at__isnull=True)
|
|
426
559
|
.exclude(status=TaskState.STATUS_CANCELLED)
|
|
427
560
|
)
|
|
@@ -476,7 +609,6 @@ class WorkflowHistoryDetailView(
|
|
|
476
609
|
context.update(
|
|
477
610
|
{
|
|
478
611
|
"object": self.object,
|
|
479
|
-
"object_icon": self.object_icon,
|
|
480
612
|
"workflow_state": self.workflow_state,
|
|
481
613
|
"tasks": self.tasks,
|
|
482
614
|
"task_states_by_revision": self.task_states_by_revision,
|
|
@@ -8,7 +8,6 @@ from django.core.exceptions import (
|
|
|
8
8
|
PermissionDenied,
|
|
9
9
|
)
|
|
10
10
|
from django.db import models, transaction
|
|
11
|
-
from django.db.models import Q
|
|
12
11
|
from django.db.models.constants import LOOKUP_SEP
|
|
13
12
|
from django.db.models.functions import Cast
|
|
14
13
|
from django.http import Http404, HttpResponseRedirect
|
|
@@ -29,7 +28,6 @@ from wagtail.actions.unpublish import UnpublishAction
|
|
|
29
28
|
from wagtail.admin import messages
|
|
30
29
|
from wagtail.admin.filters import WagtailFilterSet
|
|
31
30
|
from wagtail.admin.forms.models import WagtailAdminModelForm
|
|
32
|
-
from wagtail.admin.forms.search import SearchForm
|
|
33
31
|
from wagtail.admin.panels import get_edit_handler
|
|
34
32
|
from wagtail.admin.ui.components import Component, MediaContainer
|
|
35
33
|
from wagtail.admin.ui.fields import display_class_registry
|
|
@@ -43,6 +41,7 @@ from wagtail.admin.ui.tables import (
|
|
|
43
41
|
from wagtail.admin.utils import get_latest_str, get_valid_next_url_from_request
|
|
44
42
|
from wagtail.admin.views.mixins import SpreadsheetExportMixin
|
|
45
43
|
from wagtail.admin.widgets.button import (
|
|
44
|
+
Button,
|
|
46
45
|
ButtonWithDropdown,
|
|
47
46
|
HeaderButton,
|
|
48
47
|
ListingButton,
|
|
@@ -51,8 +50,8 @@ from wagtail.log_actions import log
|
|
|
51
50
|
from wagtail.log_actions import registry as log_registry
|
|
52
51
|
from wagtail.models import DraftStateMixin, Locale, ReferenceIndex
|
|
53
52
|
from wagtail.models.audit_log import ModelLogEntry
|
|
54
|
-
from wagtail.search.backends import get_search_backend
|
|
55
53
|
from wagtail.search.index import class_is_indexed
|
|
54
|
+
from wagtail.utils.deprecation import RemovedInWagtail70Warning
|
|
56
55
|
|
|
57
56
|
from .base import BaseListingView, WagtailAdminTemplateMixin
|
|
58
57
|
from .mixins import BeforeAfterHookMixin, HookResponseMixin, LocaleMixin, PanelMixin
|
|
@@ -74,57 +73,40 @@ class IndexView(
|
|
|
74
73
|
inspect_url_name = None
|
|
75
74
|
delete_url_name = None
|
|
76
75
|
any_permission_required = ["add", "change", "delete", "view"]
|
|
77
|
-
search_fields = None
|
|
78
|
-
search_backend_name = "default"
|
|
79
|
-
is_searchable = None
|
|
80
|
-
search_kwarg = "q"
|
|
81
76
|
columns = None # If not explicitly specified, will be derived from list_display
|
|
82
77
|
list_display = ["__str__", UpdatedAtColumn()]
|
|
83
78
|
list_filter = None
|
|
84
79
|
show_other_searches = False
|
|
85
80
|
|
|
86
|
-
def setup(self, request, *args, **kwargs):
|
|
87
|
-
super().setup(request, *args, **kwargs)
|
|
88
|
-
|
|
89
|
-
if not self.filterset_class:
|
|
90
|
-
# Allow filterset_class to be dynamically constructed from list_filter
|
|
91
|
-
self.filterset_class = self.get_filterset_class()
|
|
92
|
-
|
|
93
|
-
self.setup_search()
|
|
94
|
-
|
|
95
|
-
def setup_search(self):
|
|
96
|
-
self.is_searchable = self.get_is_searchable()
|
|
97
|
-
self.search_url = self.get_search_url()
|
|
98
|
-
self.search_form = self.get_search_form()
|
|
99
|
-
self.is_searching = False
|
|
100
|
-
self.search_query = None
|
|
101
|
-
|
|
102
|
-
if self.search_form and self.search_form.is_valid():
|
|
103
|
-
self.search_query = self.search_form.cleaned_data[self.search_kwarg]
|
|
104
|
-
self.is_searching = bool(self.search_query)
|
|
105
|
-
|
|
106
|
-
def get_is_searchable(self):
|
|
107
|
-
if self.model is None:
|
|
108
|
-
return False
|
|
109
|
-
if self.is_searchable is None:
|
|
110
|
-
return class_is_indexed(self.model) or self.search_fields
|
|
111
|
-
return self.is_searchable
|
|
112
|
-
|
|
113
81
|
def get_search_url(self):
|
|
114
|
-
|
|
115
|
-
|
|
82
|
+
# This is only used by views that do not use breadcrumbs, thus uses the
|
|
83
|
+
# legacy header.html. The search in that header template accepts both
|
|
84
|
+
# the search_url (which really should be search_url_name) and the
|
|
85
|
+
# index_results_url. This means we can advise using the latter instead,
|
|
86
|
+
# without having to instruct how to set up breadcrumbs.
|
|
87
|
+
warnings.warn(
|
|
88
|
+
"`IndexView.get_search_url` is deprecated. "
|
|
89
|
+
"Use `IndexView.get_index_results_url` instead.",
|
|
90
|
+
RemovedInWagtail70Warning,
|
|
91
|
+
)
|
|
116
92
|
return self.index_url_name
|
|
117
93
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
94
|
+
@cached_property
|
|
95
|
+
def search_url(self):
|
|
96
|
+
return self.get_search_url()
|
|
121
97
|
|
|
122
|
-
|
|
123
|
-
|
|
98
|
+
@cached_property
|
|
99
|
+
def is_searchable(self):
|
|
100
|
+
# Do not automatically enable search if the model is not indexed and
|
|
101
|
+
# search_fields is not defined.
|
|
102
|
+
if not (self.model and class_is_indexed(self.model)) and not self.search_fields:
|
|
103
|
+
return False
|
|
124
104
|
|
|
125
|
-
|
|
105
|
+
# Require the results-only view to be set up before enabling search
|
|
106
|
+
return bool(self.index_results_url or self.search_url)
|
|
126
107
|
|
|
127
|
-
|
|
108
|
+
@cached_property
|
|
109
|
+
def filterset_class(self):
|
|
128
110
|
# Allow filterset_class to be dynamically constructed from list_filter.
|
|
129
111
|
|
|
130
112
|
# If the model is translatable, ensure a ``WagtailFilterSet`` subclass
|
|
@@ -197,43 +179,6 @@ class IndexView(
|
|
|
197
179
|
|
|
198
180
|
return queryset
|
|
199
181
|
|
|
200
|
-
def get_queryset(self):
|
|
201
|
-
queryset = super().get_queryset()
|
|
202
|
-
queryset = self.search_queryset(queryset)
|
|
203
|
-
return queryset
|
|
204
|
-
|
|
205
|
-
def search_queryset(self, queryset):
|
|
206
|
-
if not self.is_searching:
|
|
207
|
-
return queryset
|
|
208
|
-
|
|
209
|
-
if class_is_indexed(queryset.model) and self.search_backend_name:
|
|
210
|
-
search_backend = get_search_backend(self.search_backend_name)
|
|
211
|
-
if queryset.model.get_autocomplete_search_fields():
|
|
212
|
-
return search_backend.autocomplete(
|
|
213
|
-
self.search_query,
|
|
214
|
-
queryset,
|
|
215
|
-
fields=self.search_fields,
|
|
216
|
-
order_by_relevance=(not self.is_explicitly_ordered),
|
|
217
|
-
)
|
|
218
|
-
else:
|
|
219
|
-
# fall back on non-autocompleting search
|
|
220
|
-
warnings.warn(
|
|
221
|
-
f"{queryset.model} is defined as Indexable but does not specify "
|
|
222
|
-
"any AutocompleteFields. Searches within the admin will only "
|
|
223
|
-
"respond to complete words.",
|
|
224
|
-
category=RuntimeWarning,
|
|
225
|
-
)
|
|
226
|
-
return search_backend.search(
|
|
227
|
-
self.search_query,
|
|
228
|
-
queryset,
|
|
229
|
-
fields=self.search_fields,
|
|
230
|
-
order_by_relevance=(not self.is_explicitly_ordered),
|
|
231
|
-
)
|
|
232
|
-
query = Q()
|
|
233
|
-
for field in self.search_fields or []:
|
|
234
|
-
query |= Q(**{field + "__icontains": self.search_query})
|
|
235
|
-
return queryset.filter(query)
|
|
236
|
-
|
|
237
182
|
def _get_title_column_class(self, column_class):
|
|
238
183
|
if not issubclass(column_class, ButtonsColumnMixin):
|
|
239
184
|
|
|
@@ -356,13 +301,6 @@ class IndexView(
|
|
|
356
301
|
return capfirst(self.model._meta.verbose_name_plural)
|
|
357
302
|
return self.page_title
|
|
358
303
|
|
|
359
|
-
def get_breadcrumbs_items(self):
|
|
360
|
-
if not self.model:
|
|
361
|
-
return self.breadcrumbs_items
|
|
362
|
-
return self.breadcrumbs_items + [
|
|
363
|
-
{"url": "", "label": capfirst(self.model._meta.verbose_name_plural)},
|
|
364
|
-
]
|
|
365
|
-
|
|
366
304
|
@cached_property
|
|
367
305
|
def header_buttons(self):
|
|
368
306
|
buttons = []
|
|
@@ -453,6 +391,12 @@ class IndexView(
|
|
|
453
391
|
)
|
|
454
392
|
return _("Add")
|
|
455
393
|
|
|
394
|
+
@cached_property
|
|
395
|
+
def verbose_name_plural(self):
|
|
396
|
+
if self.model:
|
|
397
|
+
return self.model._meta.verbose_name_plural
|
|
398
|
+
return None
|
|
399
|
+
|
|
456
400
|
def get_context_data(self, *args, **kwargs):
|
|
457
401
|
context = super().get_context_data(*args, **kwargs)
|
|
458
402
|
|
|
@@ -461,11 +405,12 @@ class IndexView(
|
|
|
461
405
|
context["add_url"] = context["header_action_url"] = self.add_url
|
|
462
406
|
context["header_action_label"] = self.add_item_label
|
|
463
407
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
408
|
+
# RemovedInWagtail70Warning:
|
|
409
|
+
# Remove these in favor of using search_form and index_results_url
|
|
410
|
+
if self.is_searchable and not self.index_results_url:
|
|
411
|
+
context["is_searchable"] = self.is_searchable
|
|
412
|
+
context["search_url"] = self.search_url
|
|
413
|
+
|
|
469
414
|
context["model_opts"] = self.model and self.model._meta
|
|
470
415
|
return context
|
|
471
416
|
|
|
@@ -498,6 +443,7 @@ class CreateView(
|
|
|
498
443
|
"The %(model_name)s could not be created due to errors."
|
|
499
444
|
)
|
|
500
445
|
submit_button_label = gettext_lazy("Create")
|
|
446
|
+
submit_button_active_label = gettext_lazy("Creating…")
|
|
501
447
|
actions = ["create"]
|
|
502
448
|
|
|
503
449
|
def setup(self, request, *args, **kwargs):
|
|
@@ -588,14 +534,20 @@ class CreateView(
|
|
|
588
534
|
% {"model_name": self.model and self.model._meta.verbose_name}
|
|
589
535
|
)
|
|
590
536
|
|
|
537
|
+
@cached_property
|
|
538
|
+
def has_unsaved_changes(self):
|
|
539
|
+
return self.form.is_bound
|
|
540
|
+
|
|
591
541
|
def get_context_data(self, **kwargs):
|
|
592
542
|
context = super().get_context_data(**kwargs)
|
|
593
543
|
self.form = context.get("form")
|
|
594
544
|
side_panels = self.get_side_panels()
|
|
595
545
|
context["action_url"] = self.add_url
|
|
596
546
|
context["submit_button_label"] = self.submit_button_label
|
|
547
|
+
context["submit_button_active_label"] = self.submit_button_active_label
|
|
597
548
|
context["side_panels"] = side_panels
|
|
598
549
|
context["media"] += side_panels.media
|
|
550
|
+
context["has_unsaved_changes"] = self.has_unsaved_changes
|
|
599
551
|
return context
|
|
600
552
|
|
|
601
553
|
def get_side_panels(self):
|
|
@@ -705,8 +657,10 @@ class EditView(
|
|
|
705
657
|
form_class = None
|
|
706
658
|
index_url_name = None
|
|
707
659
|
edit_url_name = None
|
|
660
|
+
copy_url_name = None
|
|
708
661
|
delete_url_name = None
|
|
709
662
|
history_url_name = None
|
|
663
|
+
inspect_url_name = None
|
|
710
664
|
usage_url_name = None
|
|
711
665
|
page_title = gettext_lazy("Editing")
|
|
712
666
|
context_object_name = None
|
|
@@ -716,6 +670,7 @@ class EditView(
|
|
|
716
670
|
success_message = gettext_lazy("%(model_name)s '%(object)s' updated.")
|
|
717
671
|
error_message = gettext_lazy("The %(model_name)s could not be saved due to errors.")
|
|
718
672
|
submit_button_label = gettext_lazy("Save")
|
|
673
|
+
submit_button_active_label = gettext_lazy("Saving…")
|
|
719
674
|
actions = ["edit"]
|
|
720
675
|
|
|
721
676
|
def setup(self, request, *args, **kwargs):
|
|
@@ -779,6 +734,42 @@ class EditView(
|
|
|
779
734
|
.first()
|
|
780
735
|
)
|
|
781
736
|
|
|
737
|
+
@cached_property
|
|
738
|
+
def can_delete(self):
|
|
739
|
+
return self.user_has_permission_for_instance("delete", self.object)
|
|
740
|
+
|
|
741
|
+
@cached_property
|
|
742
|
+
def header_more_buttons(self):
|
|
743
|
+
buttons = []
|
|
744
|
+
if copy_url := self.get_copy_url():
|
|
745
|
+
buttons.append(
|
|
746
|
+
Button(
|
|
747
|
+
_("Copy"),
|
|
748
|
+
url=copy_url,
|
|
749
|
+
icon_name="copy",
|
|
750
|
+
priority=10,
|
|
751
|
+
)
|
|
752
|
+
)
|
|
753
|
+
if self.can_delete and (delete_url := self.get_delete_url()):
|
|
754
|
+
buttons.append(
|
|
755
|
+
Button(
|
|
756
|
+
self.delete_item_label,
|
|
757
|
+
url=delete_url,
|
|
758
|
+
icon_name="bin",
|
|
759
|
+
priority=20,
|
|
760
|
+
)
|
|
761
|
+
)
|
|
762
|
+
if inspect_url := self.get_inspect_url():
|
|
763
|
+
buttons.append(
|
|
764
|
+
Button(
|
|
765
|
+
_("Inspect"),
|
|
766
|
+
url=inspect_url,
|
|
767
|
+
icon_name="info-circle",
|
|
768
|
+
priority=30,
|
|
769
|
+
)
|
|
770
|
+
)
|
|
771
|
+
return buttons
|
|
772
|
+
|
|
782
773
|
def get_edit_url(self):
|
|
783
774
|
if not self.edit_url_name:
|
|
784
775
|
raise ImproperlyConfigured(
|
|
@@ -787,6 +778,10 @@ class EditView(
|
|
|
787
778
|
)
|
|
788
779
|
return reverse(self.edit_url_name, args=(quote(self.object.pk),))
|
|
789
780
|
|
|
781
|
+
def get_copy_url(self):
|
|
782
|
+
if self.copy_url_name and self.user_has_permission("add"):
|
|
783
|
+
return reverse(self.copy_url_name, args=(quote(self.object.pk),))
|
|
784
|
+
|
|
790
785
|
def get_delete_url(self):
|
|
791
786
|
if self.delete_url_name:
|
|
792
787
|
return reverse(self.delete_url_name, args=(quote(self.object.pk),))
|
|
@@ -795,6 +790,10 @@ class EditView(
|
|
|
795
790
|
if self.history_url_name:
|
|
796
791
|
return reverse(self.history_url_name, args=(quote(self.object.pk),))
|
|
797
792
|
|
|
793
|
+
def get_inspect_url(self):
|
|
794
|
+
if self.inspect_url_name:
|
|
795
|
+
return reverse(self.inspect_url_name, args=(quote(self.object.pk),))
|
|
796
|
+
|
|
798
797
|
def get_usage_url(self):
|
|
799
798
|
if self.usage_url_name:
|
|
800
799
|
return reverse(self.usage_url_name, args=[quote(self.object.pk)])
|
|
@@ -895,6 +894,10 @@ class EditView(
|
|
|
895
894
|
messages.validation_error(self.request, error_message, form)
|
|
896
895
|
return super().form_invalid(form)
|
|
897
896
|
|
|
897
|
+
@cached_property
|
|
898
|
+
def has_unsaved_changes(self):
|
|
899
|
+
return self.form.is_bound
|
|
900
|
+
|
|
898
901
|
def get_context_data(self, **kwargs):
|
|
899
902
|
context = super().get_context_data(**kwargs)
|
|
900
903
|
self.form = context.get("form")
|
|
@@ -904,9 +907,9 @@ class EditView(
|
|
|
904
907
|
context["side_panels"] = side_panels
|
|
905
908
|
context["media"] += side_panels.media
|
|
906
909
|
context["submit_button_label"] = self.submit_button_label
|
|
907
|
-
context["
|
|
908
|
-
|
|
909
|
-
|
|
910
|
+
context["submit_button_active_label"] = self.submit_button_active_label
|
|
911
|
+
context["has_unsaved_changes"] = self.has_unsaved_changes
|
|
912
|
+
context["can_delete"] = self.can_delete
|
|
910
913
|
if context["can_delete"]:
|
|
911
914
|
context["delete_url"] = self.get_delete_url()
|
|
912
915
|
context["delete_item_label"] = self.delete_item_label
|
|
@@ -1034,7 +1037,7 @@ class DeleteView(
|
|
|
1034
1037
|
class InspectView(PermissionCheckedMixin, WagtailAdminTemplateMixin, TemplateView):
|
|
1035
1038
|
any_permission_required = ["add", "change", "delete", "view"]
|
|
1036
1039
|
template_name = "wagtailadmin/generic/inspect.html"
|
|
1037
|
-
page_title = gettext_lazy("
|
|
1040
|
+
page_title = gettext_lazy("Inspect")
|
|
1038
1041
|
model = None
|
|
1039
1042
|
index_url_name = None
|
|
1040
1043
|
edit_url_name = None
|
|
@@ -1071,12 +1074,25 @@ class InspectView(PermissionCheckedMixin, WagtailAdminTemplateMixin, TemplateVie
|
|
|
1071
1074
|
items.append(
|
|
1072
1075
|
{
|
|
1073
1076
|
"url": "",
|
|
1074
|
-
"label":
|
|
1077
|
+
"label": self.get_page_title(),
|
|
1075
1078
|
"sublabel": object_str,
|
|
1076
1079
|
}
|
|
1077
1080
|
)
|
|
1078
1081
|
return self.breadcrumbs_items + items
|
|
1079
1082
|
|
|
1083
|
+
@cached_property
|
|
1084
|
+
def header_more_buttons(self):
|
|
1085
|
+
buttons = []
|
|
1086
|
+
if edit_url := self.get_edit_url():
|
|
1087
|
+
buttons.append(
|
|
1088
|
+
Button(_("Edit"), url=edit_url, icon_name="edit", priority=10)
|
|
1089
|
+
)
|
|
1090
|
+
if delete_url := self.get_delete_url():
|
|
1091
|
+
buttons.append(
|
|
1092
|
+
Button(_("Delete"), url=delete_url, icon_name="bin", priority=20)
|
|
1093
|
+
)
|
|
1094
|
+
return buttons
|
|
1095
|
+
|
|
1080
1096
|
def get_fields(self):
|
|
1081
1097
|
fields = self.fields or [
|
|
1082
1098
|
f.name
|
|
@@ -1146,8 +1162,6 @@ class InspectView(PermissionCheckedMixin, WagtailAdminTemplateMixin, TemplateVie
|
|
|
1146
1162
|
context = super().get_context_data(**kwargs)
|
|
1147
1163
|
context["object"] = self.object
|
|
1148
1164
|
context["fields"] = self.get_fields_context()
|
|
1149
|
-
context["edit_url"] = self.get_edit_url()
|
|
1150
|
-
context["delete_url"] = self.get_delete_url()
|
|
1151
1165
|
return context
|
|
1152
1166
|
|
|
1153
1167
|
|