wagtail 6.0.1__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.
- wagtail/__init__.py +1 -1
- wagtail/admin/checks.py +51 -0
- wagtail/admin/compare.py +1 -1
- wagtail/admin/filters.py +70 -1
- wagtail/admin/forms/account.py +1 -1
- wagtail/admin/forms/collections.py +15 -0
- wagtail/admin/forms/pages.py +49 -0
- wagtail/admin/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ca/LC_MESSAGES/django.po +122 -0
- wagtail/admin/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/de/LC_MESSAGES/django.po +5 -5
- wagtail/admin/locale/en/LC_MESSAGES/django.po +474 -385
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +3 -3
- wagtail/admin/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/es/LC_MESSAGES/django.po +6 -6
- wagtail/admin/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/fr/LC_MESSAGES/django.po +70 -3
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.po +2 -6
- wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.po +2 -2
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.po +4 -0
- wagtail/admin/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hu/LC_MESSAGES/django.po +142 -2
- wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/django.po +80 -8
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.po +14 -2
- wagtail/admin/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/lv/LC_MESSAGES/django.po +154 -1
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +73 -2
- wagtail/admin/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ro/LC_MESSAGES/django.po +3 -3
- wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/django.po +145 -2
- wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sv/LC_MESSAGES/django.po +77 -3
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.po +17 -1
- wagtail/admin/panels/comment_panel.py +1 -1
- wagtail/admin/panels/field_panel.py +1 -1
- wagtail/admin/rich_text/converters/editor_html.py +3 -1
- wagtail/admin/rich_text/editors/draftail/__init__.py +28 -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/favicon.ico +0 -0
- wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
- wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +1 -1
- wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
- wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
- wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
- wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/preview-panel.js +1 -1
- wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.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/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +4 -4
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/staticfiles.py +1 -0
- wagtail/admin/templates/wagtailadmin/admin_base.html +1 -0
- wagtail/admin/templates/wagtailadmin/base.html +1 -0
- wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +3 -1
- wagtail/admin/templates/wagtailadmin/collections/edit.html +0 -1
- wagtail/admin/templates/wagtailadmin/collections/index_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/generic/base.html +1 -9
- wagtail/admin/templates/wagtailadmin/generic/form.html +4 -2
- wagtail/admin/templates/wagtailadmin/generic/history/action_cell.html +27 -0
- wagtail/admin/templates/wagtailadmin/generic/index_results.html +8 -0
- wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +3 -4
- wagtail/admin/templates/wagtailadmin/icons/keyboard.svg +1 -0
- wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +3 -1
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -15
- wagtail/admin/templates/wagtailadmin/pages/action_menu/save_draft.html +3 -1
- wagtail/admin/templates/wagtailadmin/pages/choose_parent.html +17 -0
- wagtail/admin/templates/wagtailadmin/pages/explorable_index.html +8 -0
- wagtail/admin/templates/wagtailadmin/pages/history.html +1 -61
- wagtail/admin/templates/wagtailadmin/pages/index.html +1 -5
- wagtail/admin/templates/wagtailadmin/pages/listing/_locked_indicator.html +2 -2
- wagtail/admin/templates/wagtailadmin/pages/listing/_page_title_column_header.html +25 -27
- wagtail/admin/templates/wagtailadmin/pages/page_listing_header.html +2 -1
- wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
- wagtail/admin/templates/wagtailadmin/panels/publishing/schedule_publishing_panel.html +3 -1
- wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/active_filters.html +2 -1
- wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +8 -0
- wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/headers/page_edit_header.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +21 -9
- wagtail/admin/templates/wagtailadmin/shared/human_readable_date.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +29 -0
- wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +2 -1
- wagtail/admin/templates/wagtailadmin/skeleton.html +2 -1
- wagtail/admin/templates/wagtailadmin/tables/related_objects_cell.html +9 -0
- wagtail/admin/templates/wagtailadmin/tables/title_cell.html +9 -7
- wagtail/admin/templates/wagtailadmin/widgets/draftail_rich_text_area.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/create.html +6 -23
- wagtail/admin/templates/wagtailadmin/workflows/create_task.html +6 -15
- wagtail/admin/templates/wagtailadmin/workflows/edit.html +6 -23
- wagtail/admin/templates/wagtailadmin/workflows/edit_task.html +6 -13
- wagtail/admin/templates/wagtailadmin/workflows/includes/task_usage_cell.html +4 -4
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_tasks_cell.html +18 -0
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_title_cell.html +7 -0
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_used_by_cell.html +25 -0
- wagtail/admin/templates/wagtailadmin/workflows/index.html +0 -99
- wagtail/admin/templates/wagtailadmin/workflows/index_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/workflows/task_index.html +0 -30
- wagtail/admin/templates/wagtailadmin/workflows/task_index_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/workflows/usage.html +1 -1
- wagtail/admin/templatetags/wagtailadmin_tags.py +116 -39
- wagtail/admin/tests/api/test_pages.py +26 -10
- wagtail/admin/tests/pages/test_create_page.py +10 -4
- wagtail/admin/tests/pages/test_custom_listing.py +37 -0
- wagtail/admin/tests/pages/test_edit_page.py +6 -6
- wagtail/admin/tests/pages/test_explorer_view.py +19 -18
- wagtail/admin/tests/pages/test_move_page.py +1 -1
- wagtail/admin/tests/pages/test_page_usage.py +50 -2
- wagtail/admin/tests/pages/test_parent_page_chooser_view.py +119 -0
- wagtail/admin/tests/pages/test_preview.py +18 -4
- wagtail/admin/tests/test_account_management.py +20 -1
- wagtail/admin/tests/test_audit_log.py +172 -5
- wagtail/admin/tests/test_checks.py +92 -0
- wagtail/admin/tests/test_collections_views.py +19 -5
- wagtail/admin/tests/test_compare.py +6 -6
- wagtail/admin/tests/test_dashboard.py +404 -0
- wagtail/admin/tests/test_dbwhitelister.py +4 -5
- wagtail/admin/tests/test_edit_handlers.py +2 -2
- wagtail/admin/tests/test_keyboard_shortcuts.py +84 -0
- wagtail/admin/tests/test_page_chooser.py +31 -18
- wagtail/admin/tests/test_privacy.py +36 -2
- wagtail/admin/tests/test_rich_text.py +168 -23
- wagtail/admin/tests/test_templatetags.py +411 -43
- wagtail/admin/tests/test_views.py +4 -2
- wagtail/admin/tests/test_workflows.py +531 -9
- wagtail/admin/tests/tests.py +3 -1
- wagtail/admin/tests/ui/test_tables.py +48 -1
- wagtail/admin/tests/viewsets/test_model_viewset.py +130 -23
- wagtail/admin/ui/side_panels.py +3 -1
- wagtail/admin/ui/tables/__init__.py +13 -1
- wagtail/admin/ui/tables/pages.py +17 -6
- wagtail/admin/urls/__init__.py +8 -3
- wagtail/admin/urls/pages.py +5 -0
- wagtail/admin/urls/workflows.py +10 -0
- wagtail/admin/views/chooser.py +20 -24
- wagtail/admin/views/collections.py +17 -1
- wagtail/admin/views/generic/base.py +34 -4
- wagtail/admin/views/generic/history.py +220 -51
- wagtail/admin/views/generic/mixins.py +7 -4
- wagtail/admin/views/generic/models.py +54 -47
- wagtail/admin/views/generic/multiple_upload.py +17 -8
- wagtail/admin/views/generic/usage.py +17 -11
- wagtail/admin/views/home.py +15 -12
- wagtail/admin/views/mixins.py +30 -0
- wagtail/admin/views/pages/choose_parent.py +73 -0
- wagtail/admin/views/pages/history.py +54 -66
- wagtail/admin/views/pages/listing.py +187 -106
- wagtail/admin/views/pages/usage.py +6 -1
- wagtail/admin/views/pages/utils.py +70 -1
- wagtail/admin/views/workflows.py +150 -21
- wagtail/admin/viewsets/model.py +2 -2
- wagtail/admin/viewsets/pages.py +77 -0
- wagtail/admin/wagtail_hooks.py +40 -2
- wagtail/admin/widgets/button.py +10 -10
- wagtail/api/v2/filters.py +1 -1
- wagtail/api/v2/tests/test_pages.py +1 -1
- wagtail/blocks/base.py +18 -9
- wagtail/blocks/field_block.py +9 -7
- wagtail/blocks/list_block.py +16 -6
- wagtail/blocks/static_block.py +3 -0
- wagtail/blocks/stream_block.py +58 -23
- wagtail/blocks/struct_block.py +15 -9
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +39 -47
- wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/forms/models.py +5 -5
- wagtail/contrib/forms/templates/wagtailforms/list_submissions.html +44 -33
- wagtail/contrib/forms/templates/wagtailforms/submissions_index.html +2 -63
- wagtail/contrib/forms/tests/test_models.py +26 -0
- wagtail/contrib/forms/urls.py +6 -0
- wagtail/contrib/forms/views.py +52 -49
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +34 -42
- wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/redirects/signal_handlers.py +1 -1
- wagtail/contrib/redirects/templates/wagtailredirects/index.html +1 -36
- wagtail/contrib/redirects/templates/wagtailredirects/index_results.html +18 -0
- wagtail/contrib/redirects/templates/wagtailredirects/redirect_target_cell.html +8 -0
- wagtail/contrib/redirects/tests/test_import_command.py +1 -1
- wagtail/contrib/redirects/tests/test_redirects.py +79 -8
- wagtail/contrib/redirects/urls.py +2 -1
- wagtail/contrib/redirects/views.py +85 -55
- wagtail/contrib/search_promotions/admin_urls.py +2 -1
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +41 -64
- wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.po +41 -2
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +9 -3
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +1 -16
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index_results.html +11 -0
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/list.html +0 -51
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/results.html +3 -16
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/search_promotion_column.html +15 -0
- wagtail/contrib/search_promotions/tests.py +122 -9
- wagtail/contrib/search_promotions/views.py +66 -65
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/settings/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/settings/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/tr/LC_MESSAGES/django.po +6 -2
- wagtail/contrib/settings/registry.py +10 -5
- wagtail/contrib/settings/tests/generic/test_admin.py +9 -0
- wagtail/contrib/settings/tests/site_specific/test_admin.py +10 -1
- wagtail/contrib/settings/tests/site_specific/test_model.py +3 -3
- wagtail/contrib/settings/tests/site_specific/test_templates.py +1 -1
- wagtail/contrib/settings/views.py +3 -1
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/tests/test_wagtail_hooks.py +2 -2
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
- wagtail/contrib/styleguide/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/styleguide/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/table_block/blocks.py +2 -2
- wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.po +27 -2
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.po +27 -2
- wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.po +27 -2
- wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
- wagtail/contrib/table_block/tests.py +6 -0
- wagtail/contrib/typed_table_block/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/ca/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/hu/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/typed_table_block/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/it/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/coreutils.py +3 -2
- wagtail/documents/admin_urls.py +2 -2
- wagtail/documents/locale/en/LC_MESSAGES/django.po +22 -22
- wagtail/documents/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/hr_HR/LC_MESSAGES/django.po +19 -2
- wagtail/documents/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/hu/LC_MESSAGES/django.po +16 -2
- wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/it/LC_MESSAGES/django.po +19 -2
- wagtail/documents/migrations/0013_delete_uploadeddocument.py +16 -0
- wagtail/documents/models.py +1 -20
- wagtail/documents/rich_text/__init__.py +11 -7
- wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
- wagtail/documents/templates/wagtaildocs/documents/index.html +0 -16
- wagtail/documents/tests/test_admin_views.py +155 -23
- wagtail/documents/tests/test_collection_privacy.py +55 -1
- wagtail/documents/tests/test_rich_text.py +14 -0
- wagtail/documents/views/documents.py +25 -22
- wagtail/documents/views/multiple.py +6 -7
- wagtail/documents/views/serve.py +16 -1
- wagtail/documents/wagtail_hooks.py +20 -15
- wagtail/embeds/blocks.py +5 -0
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/embeds/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/embeds/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/embeds/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/embeds/rich_text/__init__.py +1 -1
- wagtail/embeds/tests/test_rich_text.py +14 -0
- wagtail/embeds/wagtail_hooks.py +4 -14
- wagtail/fields.py +3 -48
- wagtail/images/admin_urls.py +2 -2
- wagtail/images/check_files/wagtail.jpg +0 -0
- wagtail/images/check_files/wagtail.png +0 -0
- wagtail/images/fields.py +2 -0
- wagtail/images/image_operations.py +1 -1
- wagtail/images/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ca/LC_MESSAGES/django.po +12 -0
- wagtail/images/locale/en/LC_MESSAGES/django.po +33 -45
- wagtail/images/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/hu/LC_MESSAGES/django.po +28 -2
- wagtail/images/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/it/LC_MESSAGES/django.po +14 -2
- wagtail/images/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +4 -0
- wagtail/images/migrations/0026_delete_uploadedimage.py +16 -0
- wagtail/images/models.py +49 -43
- wagtail/images/rich_text/__init__.py +18 -8
- wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
- wagtail/images/templates/wagtailimages/images/image_listing_header.html +6 -0
- wagtail/images/templates/wagtailimages/images/index.html +11 -51
- wagtail/images/tests/test_admin_views.py +119 -62
- wagtail/images/tests/test_image_operations.py +10 -0
- wagtail/images/tests/test_models.py +35 -33
- wagtail/images/tests/test_rich_text.py +14 -0
- wagtail/images/tests/utils.py +1 -1
- wagtail/images/views/images.py +35 -64
- wagtail/images/views/multiple.py +6 -7
- wagtail/images/wagtail_hooks.py +4 -14
- wagtail/locale/en/LC_MESSAGES/django.po +150 -136
- wagtail/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/es/LC_MESSAGES/django.po +3 -2
- wagtail/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/it/LC_MESSAGES/django.po +5 -5
- wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sl/LC_MESSAGES/django.po +27 -2
- wagtail/locales/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/et/LC_MESSAGES/django.po +2 -2
- wagtail/locales/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/he_IL/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/locales/tests.py +18 -3
- wagtail/locales/views.py +0 -1
- wagtail/management/commands/rebuild_references_index.py +3 -1
- wagtail/migrations/0092_alter_collectionviewrestriction_password_and_more.py +33 -0
- wagtail/migrations/0093_uploadedfile.py +53 -0
- wagtail/models/__init__.py +147 -32
- wagtail/models/i18n.py +1 -1
- wagtail/models/{collections.py → media.py} +33 -2
- wagtail/models/reference_index.py +1 -1
- wagtail/models/view_restrictions.py +10 -3
- wagtail/project_template/project_name/settings/base.py +6 -0
- wagtail/project_template/requirements.txt +1 -1
- wagtail/rich_text/__init__.py +25 -8
- wagtail/rich_text/pages.py +19 -8
- wagtail/rich_text/rewriters.py +140 -68
- wagtail/search/backends/database/mysql/mysql.py +3 -3
- wagtail/search/backends/database/postgres/postgres.py +3 -3
- wagtail/search/backends/database/sqlite/sqlite.py +2 -2
- wagtail/search/backends/elasticsearch7.py +4 -0
- wagtail/search/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/search/tests/test_postgres_backend.py +50 -0
- wagtail/sites/locale/en/LC_MESSAGES/django.po +8 -8
- wagtail/sites/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/sites/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/sites/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/sites/locale/ro/LC_MESSAGES/django.po +3 -2
- wagtail/sites/tests.py +35 -9
- wagtail/sites/views.py +3 -1
- wagtail/snippets/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/de/LC_MESSAGES/django.po +7 -8
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +16 -56
- wagtail/snippets/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/snippets/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.po +6 -2
- wagtail/snippets/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/lv/LC_MESSAGES/django.po +12 -0
- wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.po +4 -0
- 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/snippets/action_menu/publish.html +3 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/save.html +3 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/create.html +2 -3
- wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +2 -3
- wagtail/snippets/tests/test_preview.py +13 -2
- wagtail/snippets/tests/test_snippets.py +41 -16
- wagtail/snippets/tests/test_viewset.py +95 -18
- wagtail/snippets/tests/test_workflows.py +12 -0
- wagtail/snippets/views/snippets.py +1 -40
- wagtail/templatetags/wagtailcore_tags.py +1 -1
- wagtail/test/demosite/models.py +1 -1
- wagtail/test/middleware.py +14 -1
- wagtail/test/testapp/fixtures/test.json +20 -0
- wagtail/test/testapp/migrations/0001_squashed_0073_revisablechildmodel_secret_text.py +8 -8
- wagtail/test/testapp/migrations/0023_snippetchoosermodel_full_featured.py +1 -0
- wagtail/test/testapp/migrations/0034_custompermissionmodel.py +44 -0
- wagtail/test/testapp/migrations/0035_modelwithcustommanager.py +30 -0
- wagtail/test/testapp/migrations/0036_complexdefaultstreampage.py +28 -0
- wagtail/test/testapp/models.py +79 -2
- wagtail/test/testapp/templates/tests/custom_docs_password_required.html +10 -0
- wagtail/test/testapp/templates/tests/custom_page_password_required.html +10 -0
- wagtail/test/testapp/views.py +24 -2
- wagtail/test/testapp/wagtail_hooks.py +19 -0
- wagtail/test/utils/wagtail_tests.py +2 -2
- wagtail/tests/test_blocks.py +262 -1
- wagtail/tests/test_migrations.py +1 -1
- wagtail/tests/test_page_model.py +77 -0
- wagtail/tests/test_page_privacy.py +18 -1
- wagtail/tests/test_rich_text.py +95 -5
- wagtail/tests/test_streamfield.py +43 -0
- wagtail/tests/test_utils.py +8 -2
- wagtail/tests/test_views.py +52 -1
- wagtail/tests/test_whitelist.py +7 -7
- wagtail/users/forms.py +3 -1
- wagtail/users/locale/en/LC_MESSAGES/django.po +124 -96
- wagtail/users/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/hr_HR/LC_MESSAGES/django.po +13 -2
- wagtail/users/migrations/0013_userprofile_density.py +23 -0
- wagtail/users/models.py +14 -3
- wagtail/users/templates/wagtailusers/groups/create.html +1 -7
- wagtail/users/templates/wagtailusers/groups/edit.html +1 -13
- wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +46 -2
- wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -3
- wagtail/users/templates/wagtailusers/users/create.html +1 -14
- wagtail/users/templates/wagtailusers/users/edit.html +1 -14
- wagtail/users/templates/wagtailusers/users/index.html +2 -5
- wagtail/users/templates/wagtailusers/users/index_results.html +3 -13
- wagtail/users/templates/wagtailusers/users/user_cell.html +9 -0
- wagtail/users/templatetags/wagtailusers_tags.py +107 -20
- wagtail/users/tests/test_admin_views.py +669 -90
- wagtail/users/views/groups.py +58 -61
- wagtail/users/views/users.py +211 -92
- wagtail/users/wagtail_hooks.py +6 -38
- wagtail/users/widgets.py +3 -5
- wagtail/utils/text.py +1 -1
- wagtail/views.py +5 -9
- wagtail/whitelist.py +1 -1
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/METADATA +5 -6
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/RECORD +496 -477
- wagtail/admin/static/wagtailadmin/js/page-editor.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/mousetrap.min.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/urlify.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/xregexp.min.js +0 -1
- wagtail/admin/templates/wagtailadmin/collections/index.html +0 -34
- wagtail/admin/templates/wagtailadmin/pages/revisions/_actions.html +0 -22
- wagtail/admin/templates/wagtailadmin/shared/page_breadcrumbs.html +0 -55
- wagtail/admin/tests/pages/test_dashboard.py +0 -172
- wagtail/contrib/redirects/templates/wagtailredirects/results.html +0 -23
- wagtail/documents/templates/wagtaildocs/documents/list.html +0 -2
- wagtail/search/tests/test_postgres_stemming.py +0 -40
- wagtail/sites/templates/wagtailsites/create.html +0 -7
- wagtail/sites/templates/wagtailsites/edit.html +0 -7
- wagtail/snippets/templates/wagtailsnippets/snippets/revisions/_actions.html +0 -36
- wagtail/users/templates/wagtailusers/users/list.html +0 -62
- wagtail/users/urls/users.py +0 -12
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/top_level.txt +0 -0
|
@@ -16,6 +16,7 @@ from django_filters.filters import (
|
|
|
16
16
|
DateFromToRangeFilter,
|
|
17
17
|
ModelChoiceFilter,
|
|
18
18
|
ModelMultipleChoiceFilter,
|
|
19
|
+
MultipleChoiceFilter,
|
|
19
20
|
)
|
|
20
21
|
|
|
21
22
|
from wagtail.admin import messages
|
|
@@ -93,7 +94,6 @@ class WagtailAdminTemplateMixin(TemplateResponseMixin, ContextMixin):
|
|
|
93
94
|
if self._show_breadcrumbs:
|
|
94
95
|
context["breadcrumbs_items"] = self.get_breadcrumbs_items()
|
|
95
96
|
context["header_buttons"] = self.get_header_buttons()
|
|
96
|
-
context["header_more_buttons"] = self.get_header_more_buttons()
|
|
97
97
|
return context
|
|
98
98
|
|
|
99
99
|
def get_template_names(self):
|
|
@@ -120,13 +120,16 @@ class BaseObjectMixin:
|
|
|
120
120
|
def get_pk(self):
|
|
121
121
|
return unquote(str(self.kwargs[self.pk_url_kwarg]))
|
|
122
122
|
|
|
123
|
+
def get_base_object_queryset(self):
|
|
124
|
+
return self.model._default_manager.all()
|
|
125
|
+
|
|
123
126
|
def get_object(self):
|
|
124
127
|
if not self.model:
|
|
125
128
|
raise ImproperlyConfigured(
|
|
126
129
|
"Subclasses of wagtail.admin.views.generic.base.BaseObjectMixin must provide a "
|
|
127
130
|
"model attribute or a get_object method"
|
|
128
131
|
)
|
|
129
|
-
return get_object_or_404(self.
|
|
132
|
+
return get_object_or_404(self.get_base_object_queryset(), pk=self.pk)
|
|
130
133
|
|
|
131
134
|
|
|
132
135
|
class BaseOperationView(BaseObjectMixin, View):
|
|
@@ -201,7 +204,7 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView):
|
|
|
201
204
|
@cached_property
|
|
202
205
|
def filters(self):
|
|
203
206
|
if self.filterset_class:
|
|
204
|
-
filterset = self.filterset_class(self.
|
|
207
|
+
filterset = self.filterset_class(**self.get_filterset_kwargs())
|
|
205
208
|
# Don't use the filterset if it has no fields
|
|
206
209
|
if filterset.form.fields:
|
|
207
210
|
return filterset
|
|
@@ -213,6 +216,12 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView):
|
|
|
213
216
|
self.filters and self.filters.is_valid() and self.filters.form.has_changed()
|
|
214
217
|
)
|
|
215
218
|
|
|
219
|
+
def get_filterset_kwargs(self):
|
|
220
|
+
return {
|
|
221
|
+
"data": self.request.GET,
|
|
222
|
+
"request": self.request,
|
|
223
|
+
}
|
|
224
|
+
|
|
216
225
|
def filter_queryset(self, queryset):
|
|
217
226
|
if self.filters and self.filters.is_valid():
|
|
218
227
|
queryset = self.filters.filter_queryset(queryset)
|
|
@@ -262,6 +271,9 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView):
|
|
|
262
271
|
except KeyError:
|
|
263
272
|
continue # invalid filter value
|
|
264
273
|
|
|
274
|
+
if value == bound_field.initial:
|
|
275
|
+
continue # filter value is the same as the default
|
|
276
|
+
|
|
265
277
|
if isinstance(filter_def, ModelMultipleChoiceFilter):
|
|
266
278
|
field = filter_def.field
|
|
267
279
|
for item in value:
|
|
@@ -275,6 +287,17 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView):
|
|
|
275
287
|
),
|
|
276
288
|
)
|
|
277
289
|
)
|
|
290
|
+
elif isinstance(filter_def, MultipleChoiceFilter):
|
|
291
|
+
choices = {str(id): label for id, label in filter_def.field.choices}
|
|
292
|
+
for item in value:
|
|
293
|
+
filters.append(
|
|
294
|
+
ActiveFilter(
|
|
295
|
+
bound_field.auto_id,
|
|
296
|
+
filter_def.label,
|
|
297
|
+
choices.get(str(item), str(item)),
|
|
298
|
+
self.get_url_without_filter_param_value(field_name, item),
|
|
299
|
+
)
|
|
300
|
+
)
|
|
278
301
|
elif isinstance(filter_def, ModelChoiceFilter):
|
|
279
302
|
field = filter_def.field
|
|
280
303
|
filters.append(
|
|
@@ -288,13 +311,17 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView):
|
|
|
288
311
|
elif isinstance(filter_def, DateFromToRangeFilter):
|
|
289
312
|
start_date_display = date_format(value.start) if value.start else ""
|
|
290
313
|
end_date_display = date_format(value.stop) if value.stop else ""
|
|
314
|
+
widget = filter_def.field.widget
|
|
291
315
|
filters.append(
|
|
292
316
|
ActiveFilter(
|
|
293
317
|
bound_field.auto_id,
|
|
294
318
|
filter_def.label,
|
|
295
319
|
"%s - %s" % (start_date_display, end_date_display),
|
|
296
320
|
self.get_url_without_filter_param(
|
|
297
|
-
[
|
|
321
|
+
[
|
|
322
|
+
widget.suffixed(field_name, suffix)
|
|
323
|
+
for suffix in widget.suffixes
|
|
324
|
+
]
|
|
298
325
|
),
|
|
299
326
|
)
|
|
300
327
|
)
|
|
@@ -442,5 +469,8 @@ class BaseListingView(WagtailAdminTemplateMixin, BaseListView):
|
|
|
442
469
|
and self.filters
|
|
443
470
|
and self.results_only
|
|
444
471
|
)
|
|
472
|
+
context["render_buttons_fragment"] = (
|
|
473
|
+
context.get("header_buttons") and self.results_only
|
|
474
|
+
)
|
|
445
475
|
|
|
446
476
|
return context
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from datetime import timedelta
|
|
2
2
|
|
|
3
3
|
import django_filters
|
|
4
|
-
from django.contrib.admin.utils import quote
|
|
4
|
+
from django.contrib.admin.utils import quote
|
|
5
5
|
from django.core.paginator import Paginator
|
|
6
|
+
from django.forms import CheckboxSelectMultiple
|
|
6
7
|
from django.shortcuts import get_object_or_404
|
|
7
8
|
from django.urls import reverse
|
|
8
9
|
from django.utils.functional import cached_property
|
|
@@ -10,8 +11,13 @@ from django.utils.text import capfirst
|
|
|
10
11
|
from django.utils.translation import gettext, gettext_lazy
|
|
11
12
|
from django.views.generic import TemplateView
|
|
12
13
|
|
|
13
|
-
from wagtail.admin.filters import
|
|
14
|
+
from wagtail.admin.filters import (
|
|
15
|
+
DateRangePickerWidget,
|
|
16
|
+
MultipleUserFilter,
|
|
17
|
+
WagtailFilterSet,
|
|
18
|
+
)
|
|
14
19
|
from wagtail.admin.ui.tables import Column, DateColumn, InlineActionsTable, UserColumn
|
|
20
|
+
from wagtail.admin.utils import get_latest_str
|
|
15
21
|
from wagtail.admin.views.generic.base import (
|
|
16
22
|
BaseListingView,
|
|
17
23
|
BaseObjectMixin,
|
|
@@ -23,90 +29,238 @@ from wagtail.log_actions import registry as log_registry
|
|
|
23
29
|
from wagtail.models import (
|
|
24
30
|
BaseLogEntry,
|
|
25
31
|
DraftStateMixin,
|
|
26
|
-
|
|
32
|
+
PreviewableMixin,
|
|
27
33
|
Revision,
|
|
34
|
+
RevisionMixin,
|
|
28
35
|
TaskState,
|
|
29
36
|
WorkflowState,
|
|
30
37
|
)
|
|
31
38
|
|
|
32
39
|
|
|
33
|
-
def get_actions_for_filter():
|
|
40
|
+
def get_actions_for_filter(queryset):
|
|
34
41
|
# Only return those actions used by model log entries.
|
|
35
|
-
actions = set(
|
|
42
|
+
actions = set(queryset.get_actions())
|
|
36
43
|
return [action for action in log_registry.get_choices() if action[0] in actions]
|
|
37
44
|
|
|
38
45
|
|
|
39
|
-
class
|
|
40
|
-
action = django_filters.
|
|
46
|
+
class HistoryFilterSet(WagtailFilterSet):
|
|
47
|
+
action = django_filters.MultipleChoiceFilter(
|
|
41
48
|
label=gettext_lazy("Action"),
|
|
49
|
+
widget=CheckboxSelectMultiple,
|
|
42
50
|
# choices are set dynamically in __init__()
|
|
43
51
|
)
|
|
44
|
-
user =
|
|
52
|
+
user = MultipleUserFilter(
|
|
45
53
|
label=gettext_lazy("User"),
|
|
46
|
-
|
|
47
|
-
queryset
|
|
54
|
+
widget=CheckboxSelectMultiple,
|
|
55
|
+
# queryset is set dynamically in __init__()
|
|
48
56
|
)
|
|
49
57
|
timestamp = django_filters.DateFromToRangeFilter(
|
|
50
58
|
label=gettext_lazy("Date"), widget=DateRangePickerWidget
|
|
51
59
|
)
|
|
52
60
|
|
|
53
|
-
class Meta:
|
|
54
|
-
model = ModelLogEntry
|
|
55
|
-
fields = ["action", "user", "timestamp"]
|
|
56
|
-
|
|
57
61
|
def __init__(self, *args, **kwargs):
|
|
58
62
|
super().__init__(*args, **kwargs)
|
|
59
|
-
|
|
63
|
+
actions = get_actions_for_filter(self.queryset)
|
|
64
|
+
if not actions:
|
|
65
|
+
del self.filters["action"]
|
|
66
|
+
else:
|
|
67
|
+
self.filters["action"].extra["choices"] = actions
|
|
68
|
+
|
|
69
|
+
users = self.queryset.get_users()
|
|
70
|
+
if not users.exists():
|
|
71
|
+
del self.filters["user"]
|
|
72
|
+
else:
|
|
73
|
+
self.filters["user"].extra["queryset"] = users
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ActionColumn(Column):
|
|
77
|
+
def __init__(self, *args, object, url_names, user_can_unschedule, **kwargs):
|
|
78
|
+
super().__init__(*args, **kwargs)
|
|
79
|
+
self.object = object
|
|
80
|
+
self.url_names = url_names
|
|
81
|
+
self.user_can_unschedule = user_can_unschedule
|
|
82
|
+
self.revision_enabled = isinstance(object, RevisionMixin)
|
|
83
|
+
self.draftstate_enabled = isinstance(object, DraftStateMixin)
|
|
84
|
+
|
|
85
|
+
@cached_property
|
|
86
|
+
def cell_template_name(self):
|
|
87
|
+
if self.revision_enabled:
|
|
88
|
+
return "wagtailadmin/generic/history/action_cell.html"
|
|
89
|
+
return super().cell_template_name
|
|
90
|
+
|
|
91
|
+
def get_status(self, instance, parent_context):
|
|
92
|
+
if self.draftstate_enabled:
|
|
93
|
+
if (
|
|
94
|
+
instance.action == "wagtail.publish"
|
|
95
|
+
and instance.revision_id == self.object.live_revision_id
|
|
96
|
+
):
|
|
97
|
+
return gettext("Live version")
|
|
98
|
+
elif (
|
|
99
|
+
instance.content_changed
|
|
100
|
+
and instance.revision_id == self.object.latest_revision_id
|
|
101
|
+
):
|
|
102
|
+
return gettext("Current draft")
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
def get_actions(self, instance, parent_context):
|
|
106
|
+
actions = []
|
|
107
|
+
|
|
108
|
+
# Do not show the revision actions if the log entry:
|
|
109
|
+
# - has no revision attached
|
|
110
|
+
# - has no content changes
|
|
111
|
+
# - is a "publish" action
|
|
112
|
+
# (because we want to show the options on the "edit" action instead)
|
|
113
|
+
if (
|
|
114
|
+
not self.revision_enabled
|
|
115
|
+
or not instance.revision_id
|
|
116
|
+
or not instance.content_changed
|
|
117
|
+
or instance.action == "wagtail.publish"
|
|
118
|
+
):
|
|
119
|
+
return actions
|
|
120
|
+
|
|
121
|
+
if (
|
|
122
|
+
isinstance(self.object, PreviewableMixin)
|
|
123
|
+
and self.object.is_previewable()
|
|
124
|
+
and (url_name := self.url_names.get("revisions_view"))
|
|
125
|
+
):
|
|
126
|
+
url = reverse(url_name, args=(quote(self.object.pk), instance.revision_id))
|
|
127
|
+
action = {"url": url, "label": gettext("Preview")}
|
|
128
|
+
actions.append(action)
|
|
129
|
+
|
|
130
|
+
if instance.revision_id == self.object.latest_revision_id:
|
|
131
|
+
if url_name := self.url_names.get("edit"):
|
|
132
|
+
url = reverse(url_name, args=(quote(self.object.pk),))
|
|
133
|
+
action = {"url": url, "label": gettext("Edit")}
|
|
134
|
+
actions.append(action)
|
|
135
|
+
elif url_name := self.url_names.get("revisions_revert"):
|
|
136
|
+
url = reverse(url_name, args=(quote(self.object.pk), instance.revision_id))
|
|
137
|
+
action = {"url": url, "label": gettext("Review this version")}
|
|
138
|
+
actions.append(action)
|
|
139
|
+
|
|
140
|
+
if url_name := self.url_names.get("revisions_compare"):
|
|
141
|
+
if instance.previous_revision_id:
|
|
142
|
+
url = reverse(
|
|
143
|
+
url_name,
|
|
144
|
+
args=(
|
|
145
|
+
quote(self.object.pk),
|
|
146
|
+
instance.previous_revision_id,
|
|
147
|
+
instance.revision_id,
|
|
148
|
+
),
|
|
149
|
+
)
|
|
150
|
+
action = {"url": url, "label": gettext("Compare with previous version")}
|
|
151
|
+
actions.append(action)
|
|
152
|
+
if instance.revision_id != self.object.latest_revision_id:
|
|
153
|
+
url = reverse(
|
|
154
|
+
url_name,
|
|
155
|
+
args=(quote(self.object.pk), instance.revision_id, "latest"),
|
|
156
|
+
)
|
|
157
|
+
action = {"url": url, "label": gettext("Compare with current version")}
|
|
158
|
+
actions.append(action)
|
|
159
|
+
|
|
160
|
+
if (
|
|
161
|
+
(url_name := self.url_names.get("revisions_unschedule"))
|
|
162
|
+
and instance.revision.approved_go_live_at
|
|
163
|
+
and self.user_can_unschedule
|
|
164
|
+
):
|
|
165
|
+
url = reverse(url_name, args=(quote(self.object.pk), instance.revision_id))
|
|
166
|
+
action = {"url": url, "label": gettext("Cancel scheduled publish")}
|
|
167
|
+
actions.append(action)
|
|
168
|
+
|
|
169
|
+
return actions
|
|
170
|
+
|
|
171
|
+
def get_cell_context_data(self, instance, parent_context):
|
|
172
|
+
context = super().get_cell_context_data(instance, parent_context)
|
|
173
|
+
context["status"] = self.get_status(instance, parent_context)
|
|
174
|
+
context["actions"] = self.get_actions(instance, parent_context)
|
|
175
|
+
return context
|
|
60
176
|
|
|
61
177
|
|
|
62
|
-
class
|
|
178
|
+
class LogEntryUserColumn(UserColumn):
|
|
179
|
+
def __init__(self, name, **kwargs):
|
|
180
|
+
# Instead of accepting a blank_display_name arg, we'll make use of the
|
|
181
|
+
# BaseLogEntry.user_display_name property which also handles the display
|
|
182
|
+
# name for a deleted user (as the BaseLogEntry still stores the ID).
|
|
183
|
+
super().__init__(name, blank_display_name=None, **kwargs)
|
|
184
|
+
|
|
185
|
+
def get_cell_context_data(self, instance, parent_context):
|
|
186
|
+
context = super().get_cell_context_data(instance, parent_context)
|
|
187
|
+
if not context["display_name"]:
|
|
188
|
+
context["display_name"] = instance.user_display_name
|
|
189
|
+
return context
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class HistoryView(PermissionCheckedMixin, BaseObjectMixin, BaseListingView):
|
|
63
193
|
any_permission_required = ["add", "change", "delete"]
|
|
64
194
|
page_title = gettext_lazy("History")
|
|
65
195
|
results_template_name = "wagtailadmin/generic/history_results.html"
|
|
66
|
-
history_url_name = None
|
|
67
|
-
history_results_url_name = None
|
|
68
196
|
header_icon = "history"
|
|
69
197
|
is_searchable = False
|
|
70
198
|
paginate_by = 20
|
|
71
|
-
filterset_class =
|
|
199
|
+
filterset_class = HistoryFilterSet
|
|
72
200
|
table_class = InlineActionsTable
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
UserColumn("user", blank_display_name="system"),
|
|
76
|
-
DateColumn("timestamp", label=gettext_lazy("Date")),
|
|
77
|
-
]
|
|
201
|
+
history_url_name = None
|
|
202
|
+
history_results_url_name = None
|
|
78
203
|
edit_url_name = None
|
|
204
|
+
revisions_view_url_name = None
|
|
205
|
+
revisions_revert_url_name = None
|
|
206
|
+
revisions_compare_url_name = None
|
|
207
|
+
revisions_unschedule_url_name = None
|
|
79
208
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
209
|
+
@cached_property
|
|
210
|
+
def columns(self):
|
|
211
|
+
return [
|
|
212
|
+
ActionColumn(
|
|
213
|
+
"message",
|
|
214
|
+
label=gettext_lazy("Action"),
|
|
215
|
+
object=self.object,
|
|
216
|
+
url_names={
|
|
217
|
+
"edit": self.edit_url_name,
|
|
218
|
+
"revisions_view": self.revisions_view_url_name,
|
|
219
|
+
"revisions_revert": self.revisions_revert_url_name,
|
|
220
|
+
"revisions_compare": self.revisions_compare_url_name,
|
|
221
|
+
"revisions_unschedule": self.revisions_unschedule_url_name,
|
|
222
|
+
},
|
|
223
|
+
user_can_unschedule=self.user_can_unschedule(),
|
|
224
|
+
),
|
|
225
|
+
LogEntryUserColumn("user", width="25%"),
|
|
226
|
+
DateColumn("timestamp", label=gettext_lazy("Date"), width="15%"),
|
|
227
|
+
]
|
|
84
228
|
|
|
85
|
-
def
|
|
86
|
-
|
|
87
|
-
if
|
|
88
|
-
return
|
|
89
|
-
return
|
|
229
|
+
def get_base_object_queryset(self):
|
|
230
|
+
queryset = super().get_base_object_queryset()
|
|
231
|
+
if issubclass(queryset.model, RevisionMixin):
|
|
232
|
+
return queryset.select_related("latest_revision")
|
|
233
|
+
return queryset
|
|
90
234
|
|
|
91
235
|
def get_page_subtitle(self):
|
|
92
|
-
return
|
|
236
|
+
return get_latest_str(self.object)
|
|
93
237
|
|
|
94
238
|
def get_breadcrumbs_items(self):
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
239
|
+
items = []
|
|
240
|
+
if self.index_url_name:
|
|
241
|
+
items.append(
|
|
242
|
+
{
|
|
243
|
+
"url": reverse(self.index_url_name),
|
|
244
|
+
"label": capfirst(self.model._meta.verbose_name_plural),
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
edit_url = self.get_edit_url(self.object)
|
|
248
|
+
obj_name = self.get_page_subtitle()
|
|
249
|
+
if edit_url:
|
|
250
|
+
items.append(
|
|
251
|
+
{
|
|
252
|
+
"url": edit_url,
|
|
253
|
+
"label": obj_name,
|
|
254
|
+
}
|
|
255
|
+
)
|
|
256
|
+
items.append(
|
|
104
257
|
{
|
|
105
258
|
"url": "",
|
|
106
259
|
"label": gettext("History"),
|
|
107
|
-
"sublabel":
|
|
108
|
-
}
|
|
109
|
-
|
|
260
|
+
"sublabel": obj_name,
|
|
261
|
+
}
|
|
262
|
+
)
|
|
263
|
+
return self.breadcrumbs_items + items
|
|
110
264
|
|
|
111
265
|
@cached_property
|
|
112
266
|
def header_buttons(self):
|
|
@@ -136,19 +290,34 @@ class HistoryView(PermissionCheckedMixin, BaseListingView):
|
|
|
136
290
|
def get_index_results_url(self):
|
|
137
291
|
return self.get_history_results_url(self.object)
|
|
138
292
|
|
|
293
|
+
def user_can_unschedule(self):
|
|
294
|
+
return self.user_has_permission("publish")
|
|
295
|
+
|
|
139
296
|
def get_context_data(self, *args, object_list=None, **kwargs):
|
|
140
297
|
context = super().get_context_data(*args, object_list=object_list, **kwargs)
|
|
141
298
|
context["object"] = self.object
|
|
142
299
|
context["model_opts"] = BaseLogEntry._meta
|
|
143
300
|
return context
|
|
144
301
|
|
|
145
|
-
def
|
|
146
|
-
queryset = log_registry.get_logs_for_instance(self.object)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
302
|
+
def get_base_queryset(self):
|
|
303
|
+
queryset = log_registry.get_logs_for_instance(self.object)
|
|
304
|
+
return self._annotate_queryset(queryset)
|
|
305
|
+
|
|
306
|
+
def _annotate_queryset(self, queryset):
|
|
307
|
+
queryset = queryset.select_related("user", "user__wagtail_userprofile")
|
|
308
|
+
if isinstance(self.object, RevisionMixin):
|
|
309
|
+
queryset = queryset.select_related("revision").annotate(
|
|
310
|
+
previous_revision_id=Revision.objects.previous_revision_id_subquery(),
|
|
311
|
+
)
|
|
150
312
|
return queryset
|
|
151
313
|
|
|
314
|
+
def get_filterset_kwargs(self):
|
|
315
|
+
# Pass custom queryset so the FilterSet can use it when initialising the
|
|
316
|
+
# filters, instead of using the default model.objects.all() queryset.
|
|
317
|
+
kwargs = super().get_filterset_kwargs()
|
|
318
|
+
kwargs["queryset"] = self.get_base_queryset()
|
|
319
|
+
return kwargs
|
|
320
|
+
|
|
152
321
|
|
|
153
322
|
class WorkflowHistoryView(BaseObjectMixin, WagtailAdminTemplateMixin, TemplateView):
|
|
154
323
|
template_name = "wagtailadmin/shared/workflow_history/index.html"
|
|
@@ -101,10 +101,13 @@ class BeforeAfterHookMixin(HookResponseMixin):
|
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
class LocaleMixin:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
@cached_property
|
|
105
|
+
def locale(self):
|
|
106
|
+
return self.get_locale()
|
|
107
|
+
|
|
108
|
+
@cached_property
|
|
109
|
+
def translations(self):
|
|
110
|
+
return self.get_translations() if self.locale else []
|
|
108
111
|
|
|
109
112
|
def get_locale(self):
|
|
110
113
|
if not getattr(self, "model", None):
|
|
@@ -9,6 +9,7 @@ from django.core.exceptions import (
|
|
|
9
9
|
)
|
|
10
10
|
from django.db import models, transaction
|
|
11
11
|
from django.db.models import Q
|
|
12
|
+
from django.db.models.constants import LOOKUP_SEP
|
|
12
13
|
from django.db.models.functions import Cast
|
|
13
14
|
from django.http import Http404, HttpResponseRedirect
|
|
14
15
|
from django.shortcuts import get_object_or_404, redirect
|
|
@@ -41,7 +42,6 @@ from wagtail.admin.ui.tables import (
|
|
|
41
42
|
from wagtail.admin.utils import get_latest_str, get_valid_next_url_from_request
|
|
42
43
|
from wagtail.admin.views.mixins import SpreadsheetExportMixin
|
|
43
44
|
from wagtail.admin.widgets.button import (
|
|
44
|
-
Button,
|
|
45
45
|
ButtonWithDropdown,
|
|
46
46
|
HeaderButton,
|
|
47
47
|
ListingButton,
|
|
@@ -233,7 +233,7 @@ class IndexView(
|
|
|
233
233
|
query |= Q(**{field + "__icontains": self.search_query})
|
|
234
234
|
return queryset.filter(query)
|
|
235
235
|
|
|
236
|
-
def
|
|
236
|
+
def _get_title_column_class(self, column_class):
|
|
237
237
|
if not issubclass(column_class, ButtonsColumnMixin):
|
|
238
238
|
|
|
239
239
|
def get_buttons(column, instance, *args, **kwargs):
|
|
@@ -244,6 +244,10 @@ class IndexView(
|
|
|
244
244
|
(ButtonsColumnMixin, column_class),
|
|
245
245
|
{"get_buttons": get_buttons},
|
|
246
246
|
)
|
|
247
|
+
return column_class
|
|
248
|
+
|
|
249
|
+
def _get_title_column(self, field_name, column_class=TitleColumn, **kwargs):
|
|
250
|
+
column_class = self._get_title_column_class(column_class)
|
|
247
251
|
if not self.model:
|
|
248
252
|
return column_class(
|
|
249
253
|
"name",
|
|
@@ -256,7 +260,32 @@ class IndexView(
|
|
|
256
260
|
)
|
|
257
261
|
|
|
258
262
|
def _get_custom_column(self, field_name, column_class=Column, **kwargs):
|
|
259
|
-
|
|
263
|
+
lookups = (
|
|
264
|
+
[field_name]
|
|
265
|
+
if hasattr(self.model, field_name)
|
|
266
|
+
else field_name.split(LOOKUP_SEP)
|
|
267
|
+
)
|
|
268
|
+
*relations, field = lookups
|
|
269
|
+
model_class = self.model
|
|
270
|
+
|
|
271
|
+
# Iterate over the relation list to try to get the last model
|
|
272
|
+
# where the field exists
|
|
273
|
+
foreign_field_name = ""
|
|
274
|
+
for model in relations:
|
|
275
|
+
foreign_field = model_class._meta.get_field(model)
|
|
276
|
+
foreign_field_name = foreign_field.verbose_name
|
|
277
|
+
model_class = foreign_field.related_model
|
|
278
|
+
|
|
279
|
+
label, attr = label_for_field(field, model_class, return_attr=True)
|
|
280
|
+
|
|
281
|
+
# For some languages, it may be more appropriate to put the field label
|
|
282
|
+
# before the related model name
|
|
283
|
+
if foreign_field_name:
|
|
284
|
+
label = _("%(related_model_name)s %(field_label)s") % {
|
|
285
|
+
"related_model_name": foreign_field_name,
|
|
286
|
+
"field_label": label,
|
|
287
|
+
}
|
|
288
|
+
|
|
260
289
|
sort_key = getattr(attr, "admin_order_field", None)
|
|
261
290
|
|
|
262
291
|
# attr is None if the field is an actual database field,
|
|
@@ -264,8 +293,12 @@ class IndexView(
|
|
|
264
293
|
if attr is None:
|
|
265
294
|
sort_key = field_name
|
|
266
295
|
|
|
296
|
+
accessor = field_name
|
|
297
|
+
# Build the dotted relation if needed, for use in multigetattr
|
|
298
|
+
if relations:
|
|
299
|
+
accessor = ".".join(lookups)
|
|
267
300
|
return column_class(
|
|
268
|
-
|
|
301
|
+
accessor,
|
|
269
302
|
label=capfirst(label),
|
|
270
303
|
sort_key=sort_key,
|
|
271
304
|
**kwargs,
|
|
@@ -334,42 +367,10 @@ class IndexView(
|
|
|
334
367
|
self.add_item_label,
|
|
335
368
|
url=self.add_url,
|
|
336
369
|
icon_name="plus",
|
|
337
|
-
attrs={"data-w-link-reflect-keys-value": '["locale"]'},
|
|
338
370
|
)
|
|
339
371
|
)
|
|
340
372
|
return buttons
|
|
341
373
|
|
|
342
|
-
@cached_property
|
|
343
|
-
def header_more_buttons(self):
|
|
344
|
-
buttons = []
|
|
345
|
-
if self.list_export:
|
|
346
|
-
buttons.append(
|
|
347
|
-
Button(
|
|
348
|
-
_("Download XLSX"),
|
|
349
|
-
url=self.xlsx_export_url,
|
|
350
|
-
icon_name="download",
|
|
351
|
-
priority=90,
|
|
352
|
-
attrs={
|
|
353
|
-
"data-controller": "w-link",
|
|
354
|
-
"data-w-link-preserve-keys-value": '["export"]',
|
|
355
|
-
},
|
|
356
|
-
)
|
|
357
|
-
)
|
|
358
|
-
buttons.append(
|
|
359
|
-
Button(
|
|
360
|
-
_("Download CSV"),
|
|
361
|
-
url=self.csv_export_url,
|
|
362
|
-
icon_name="download",
|
|
363
|
-
priority=100,
|
|
364
|
-
attrs={
|
|
365
|
-
"data-controller": "w-link",
|
|
366
|
-
"data-w-link-preserve-keys-value": '["export"]',
|
|
367
|
-
},
|
|
368
|
-
)
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
return buttons
|
|
372
|
-
|
|
373
374
|
def get_list_more_buttons(self, instance):
|
|
374
375
|
buttons = []
|
|
375
376
|
edit_url = self.get_edit_url(instance)
|
|
@@ -606,14 +607,16 @@ class CreateView(
|
|
|
606
607
|
return context
|
|
607
608
|
|
|
608
609
|
def get_side_panels(self):
|
|
609
|
-
side_panels = [
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
610
|
+
side_panels = []
|
|
611
|
+
if self.locale:
|
|
612
|
+
side_panels.append(
|
|
613
|
+
StatusSidePanel(
|
|
614
|
+
self.form.instance,
|
|
615
|
+
self.request,
|
|
616
|
+
locale=self.locale,
|
|
617
|
+
translations=self.translations,
|
|
618
|
+
)
|
|
615
619
|
)
|
|
616
|
-
]
|
|
617
620
|
return MediaContainer(side_panels)
|
|
618
621
|
|
|
619
622
|
def get_translations(self):
|
|
@@ -668,7 +671,7 @@ class CreateView(
|
|
|
668
671
|
|
|
669
672
|
class CopyView(CreateView):
|
|
670
673
|
def get_object(self, queryset=None):
|
|
671
|
-
return get_object_or_404(self.model, pk=self.kwargs["pk"])
|
|
674
|
+
return get_object_or_404(self.model, pk=unquote(str(self.kwargs["pk"])))
|
|
672
675
|
|
|
673
676
|
def get_form_kwargs(self):
|
|
674
677
|
return {**super().get_form_kwargs(), "instance": self.get_object()}
|
|
@@ -719,7 +722,7 @@ class EditView(
|
|
|
719
722
|
return super().get_object(queryset)
|
|
720
723
|
|
|
721
724
|
def get_page_subtitle(self):
|
|
722
|
-
return
|
|
725
|
+
return get_latest_str(self.object)
|
|
723
726
|
|
|
724
727
|
def get_breadcrumbs_items(self):
|
|
725
728
|
if not self.model:
|
|
@@ -732,7 +735,7 @@ class EditView(
|
|
|
732
735
|
"label": capfirst(self.model._meta.verbose_name_plural),
|
|
733
736
|
}
|
|
734
737
|
)
|
|
735
|
-
items.append({"url": "", "label":
|
|
738
|
+
items.append({"url": "", "label": self.get_page_subtitle()})
|
|
736
739
|
return self.breadcrumbs_items + items
|
|
737
740
|
|
|
738
741
|
def get_side_panels(self):
|
|
@@ -754,7 +757,11 @@ class EditView(
|
|
|
754
757
|
return MediaContainer(side_panels)
|
|
755
758
|
|
|
756
759
|
def get_last_updated_info(self):
|
|
757
|
-
return
|
|
760
|
+
return (
|
|
761
|
+
log_registry.get_logs_for_instance(self.object)
|
|
762
|
+
.select_related("user")
|
|
763
|
+
.first()
|
|
764
|
+
)
|
|
758
765
|
|
|
759
766
|
def get_edit_url(self):
|
|
760
767
|
if not self.edit_url_name:
|