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
wagtail/test/testapp/models.py
CHANGED
|
@@ -556,7 +556,7 @@ class FormPage(AbstractEmailForm):
|
|
|
556
556
|
|
|
557
557
|
# This is redundant (SubmissionsListView is the default view class), but importing
|
|
558
558
|
# SubmissionsListView in this models.py helps us to confirm that this recipe
|
|
559
|
-
# https://docs.wagtail.org/en/stable/reference/contrib/forms/
|
|
559
|
+
# https://docs.wagtail.org/en/stable/reference/contrib/forms/customization.html#customise-form-submissions-listing-in-wagtail-admin
|
|
560
560
|
# works without triggering circular dependency issues -
|
|
561
561
|
# see https://github.com/wagtail/wagtail/issues/6265
|
|
562
562
|
submissions_list_view_class = SubmissionsListView
|
|
@@ -1011,6 +1011,17 @@ class AdvertWithTabbedInterface(models.Model):
|
|
|
1011
1011
|
register_snippet(AdvertWithTabbedInterface)
|
|
1012
1012
|
|
|
1013
1013
|
|
|
1014
|
+
class CustomManager(models.Manager):
|
|
1015
|
+
pass
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
class ModelWithCustomManager(models.Model):
|
|
1019
|
+
instances = CustomManager()
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
register_snippet(ModelWithCustomManager)
|
|
1023
|
+
|
|
1024
|
+
|
|
1014
1025
|
# Models with RevisionMixin
|
|
1015
1026
|
class RevisableModel(RevisionMixin, models.Model):
|
|
1016
1027
|
text = models.TextField()
|
|
@@ -1423,7 +1434,11 @@ class EventPageChooserModel(models.Model):
|
|
|
1423
1434
|
class SnippetChooserModel(models.Model):
|
|
1424
1435
|
advert = models.ForeignKey(Advert, help_text="help text", on_delete=models.CASCADE)
|
|
1425
1436
|
full_featured = models.ForeignKey(
|
|
1426
|
-
FullFeaturedSnippet,
|
|
1437
|
+
FullFeaturedSnippet,
|
|
1438
|
+
on_delete=models.CASCADE,
|
|
1439
|
+
null=True,
|
|
1440
|
+
blank=True,
|
|
1441
|
+
verbose_name="Chosen snippet",
|
|
1427
1442
|
)
|
|
1428
1443
|
|
|
1429
1444
|
panels = [
|
|
@@ -1611,6 +1626,36 @@ class DefaultStreamPage(Page):
|
|
|
1611
1626
|
]
|
|
1612
1627
|
|
|
1613
1628
|
|
|
1629
|
+
class ComplexDefaultStreamPage(Page):
|
|
1630
|
+
body = StreamField(
|
|
1631
|
+
[
|
|
1632
|
+
("text", CharBlock()),
|
|
1633
|
+
("rich_text", RichTextBlock()),
|
|
1634
|
+
(
|
|
1635
|
+
"books",
|
|
1636
|
+
StreamBlock(
|
|
1637
|
+
[
|
|
1638
|
+
("title", CharBlock()),
|
|
1639
|
+
("author", CharBlock()),
|
|
1640
|
+
]
|
|
1641
|
+
),
|
|
1642
|
+
),
|
|
1643
|
+
],
|
|
1644
|
+
default=[
|
|
1645
|
+
("rich_text", "<p>My <i>lovely</i> books</p>"),
|
|
1646
|
+
(
|
|
1647
|
+
"books",
|
|
1648
|
+
[("title", "The Great Gatsby"), ("author", "F. Scott Fitzgerald")],
|
|
1649
|
+
),
|
|
1650
|
+
],
|
|
1651
|
+
)
|
|
1652
|
+
|
|
1653
|
+
content_panels = [
|
|
1654
|
+
FieldPanel("title"),
|
|
1655
|
+
FieldPanel("body"),
|
|
1656
|
+
]
|
|
1657
|
+
|
|
1658
|
+
|
|
1614
1659
|
class MTIBasePage(Page):
|
|
1615
1660
|
is_creatable = False
|
|
1616
1661
|
|
|
@@ -2256,3 +2301,35 @@ class CustomPermissionTester(PagePermissionTester):
|
|
|
2256
2301
|
class CustomPermissionPage(Page):
|
|
2257
2302
|
def permissions_for_user(self, user):
|
|
2258
2303
|
return CustomPermissionTester(user, self)
|
|
2304
|
+
|
|
2305
|
+
|
|
2306
|
+
class CustomPermissionModel(models.Model):
|
|
2307
|
+
text = models.TextField(default="Tailwag")
|
|
2308
|
+
|
|
2309
|
+
class Meta:
|
|
2310
|
+
verbose_name = "ADVANCED permission model"
|
|
2311
|
+
verbose_name_plural = "ADVANCED permission models"
|
|
2312
|
+
|
|
2313
|
+
# Django's default_permissions are ("add", "change", "delete", "view").
|
|
2314
|
+
# Django will generate permissions for each of these actions with the
|
|
2315
|
+
# format f"{action}_{model_name}" and the label "Can {action} {verbose_name}".
|
|
2316
|
+
# This means if the action is "bulk_update", the codename will be
|
|
2317
|
+
# "bulk_update_custompermissionmodel" and the label will be
|
|
2318
|
+
# "Can bulk_update ADVANCED permission model".
|
|
2319
|
+
# See https://github.com/django/django/blob/stable/5.0.x/django/contrib/auth/management/__init__.py#L22-L35
|
|
2320
|
+
default_permissions = ("add", "change", "delete", "view", "bulk_update")
|
|
2321
|
+
|
|
2322
|
+
# Permissions with completely custom codenames and labels
|
|
2323
|
+
permissions = [
|
|
2324
|
+
# Starts with can_ and "Can "
|
|
2325
|
+
("can_start_trouble", "Can start trouble"),
|
|
2326
|
+
# Doesn't start with can_ and "Can "
|
|
2327
|
+
("cause_chaos", "Cause chaos for advanced permission model"),
|
|
2328
|
+
# Starts with an action similar to a built-in permission "change_"
|
|
2329
|
+
("change_text", "Change text"),
|
|
2330
|
+
# Without any _ and the label ends with the default verbose_name
|
|
2331
|
+
("control", "Manage custom permission model"),
|
|
2332
|
+
]
|
|
2333
|
+
|
|
2334
|
+
|
|
2335
|
+
register_snippet(CustomPermissionModel)
|
wagtail/test/testapp/views.py
CHANGED
|
@@ -12,14 +12,16 @@ from wagtail.admin import messages
|
|
|
12
12
|
from wagtail.admin.auth import user_passes_test
|
|
13
13
|
from wagtail.admin.filters import WagtailFilterSet
|
|
14
14
|
from wagtail.admin.panels import FieldPanel
|
|
15
|
-
from wagtail.admin.ui.tables import BooleanColumn, UpdatedAtColumn
|
|
15
|
+
from wagtail.admin.ui.tables import BooleanColumn, Column, UpdatedAtColumn
|
|
16
16
|
from wagtail.admin.views.generic import DeleteView, EditView, IndexView
|
|
17
17
|
from wagtail.admin.viewsets.base import ViewSet, ViewSetGroup
|
|
18
18
|
from wagtail.admin.viewsets.chooser import ChooserViewSet
|
|
19
19
|
from wagtail.admin.viewsets.model import ModelViewSet, ModelViewSetGroup
|
|
20
|
+
from wagtail.admin.viewsets.pages import PageListingViewSet
|
|
20
21
|
from wagtail.contrib.forms.views import SubmissionsListView
|
|
21
22
|
from wagtail.test.testapp.models import (
|
|
22
23
|
Advert,
|
|
24
|
+
EventPage,
|
|
23
25
|
FeatureCompleteToy,
|
|
24
26
|
JSONBlockCountsStreamModel,
|
|
25
27
|
JSONMinMaxCountStreamModel,
|
|
@@ -49,7 +51,7 @@ def message_test(request):
|
|
|
49
51
|
|
|
50
52
|
class CustomSubmissionsListView(SubmissionsListView):
|
|
51
53
|
paginate_by = 50
|
|
52
|
-
|
|
54
|
+
default_ordering = ("submit_time",)
|
|
53
55
|
ordering_csv = ("-submit_time",)
|
|
54
56
|
|
|
55
57
|
def get_csv_filename(self):
|
|
@@ -295,3 +297,23 @@ animated_advert_chooser_viewset = AnimatedAdvertChooserViewSet(
|
|
|
295
297
|
)
|
|
296
298
|
|
|
297
299
|
AdvertChooserWidget = animated_advert_chooser_viewset.widget_class
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
class EventPageFilterSet(PageListingViewSet.filterset_class):
|
|
303
|
+
class Meta:
|
|
304
|
+
model = EventPage
|
|
305
|
+
fields = ["audience"]
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
class EventPageListingViewSet(PageListingViewSet):
|
|
309
|
+
model = EventPage
|
|
310
|
+
icon = "calendar"
|
|
311
|
+
menu_label = "Event pages"
|
|
312
|
+
add_to_admin_menu = True
|
|
313
|
+
columns = PageListingViewSet.columns + [
|
|
314
|
+
Column("audience", label="Audience", sort_key="audience"),
|
|
315
|
+
]
|
|
316
|
+
filterset_class = EventPageFilterSet
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
event_page_listing_viewset = EventPageListingViewSet("event_pages")
|
|
@@ -31,6 +31,7 @@ from wagtail.test.testapp.models import (
|
|
|
31
31
|
ModeratedModel,
|
|
32
32
|
RevisableChildModel,
|
|
33
33
|
RevisableModel,
|
|
34
|
+
SnippetChooserModel,
|
|
34
35
|
VariousOnDeleteModel,
|
|
35
36
|
)
|
|
36
37
|
from wagtail.test.testapp.views import (
|
|
@@ -39,6 +40,7 @@ from wagtail.test.testapp.views import (
|
|
|
39
40
|
SearchTestModelViewSet,
|
|
40
41
|
ToyViewSetGroup,
|
|
41
42
|
animated_advert_chooser_viewset,
|
|
43
|
+
event_page_listing_viewset,
|
|
42
44
|
)
|
|
43
45
|
|
|
44
46
|
from .forms import FavouriteColourForm
|
|
@@ -384,12 +386,24 @@ class VariousOnDeleteModelViewSet(SnippetViewSet):
|
|
|
384
386
|
inspect_view_enabled = True
|
|
385
387
|
|
|
386
388
|
|
|
389
|
+
class SnippetChooserModelViewSet(SnippetViewSet):
|
|
390
|
+
model = SnippetChooserModel
|
|
391
|
+
|
|
392
|
+
list_display = [
|
|
393
|
+
"__str__",
|
|
394
|
+
"full_featured__text",
|
|
395
|
+
"full_featured__latest_revision__created_at",
|
|
396
|
+
]
|
|
397
|
+
exclude_form_fields = []
|
|
398
|
+
|
|
399
|
+
|
|
387
400
|
register_snippet(FullFeaturedSnippet, viewset=FullFeaturedSnippetViewSet)
|
|
388
401
|
register_snippet(DraftStateModel, viewset=DraftStateModelViewSet)
|
|
389
402
|
# Works with both classes and instances
|
|
390
403
|
register_snippet(ModeratedModelViewSet())
|
|
391
404
|
register_snippet(RevisableViewSetGroup)
|
|
392
405
|
register_snippet(VariousOnDeleteModelViewSet)
|
|
406
|
+
register_snippet(SnippetChooserModelViewSet)
|
|
393
407
|
|
|
394
408
|
|
|
395
409
|
@hooks.register("register_bulk_action")
|
|
@@ -404,3 +418,8 @@ class DisableBulkAction(SnippetBulkAction):
|
|
|
404
418
|
@hooks.register("register_admin_viewset")
|
|
405
419
|
def register_animated_advert_chooser_viewset():
|
|
406
420
|
return animated_advert_chooser_viewset
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
@hooks.register("register_admin_viewset")
|
|
424
|
+
def register_event_page_listing_viewset():
|
|
425
|
+
return event_page_listing_viewset
|
|
@@ -9,8 +9,8 @@ from django.test.testcases import assert_and_parse_html
|
|
|
9
9
|
|
|
10
10
|
class WagtailTestUtils:
|
|
11
11
|
@staticmethod
|
|
12
|
-
def get_soup(markup: Union[str, bytes]
|
|
13
|
-
return BeautifulSoup(markup, parser)
|
|
12
|
+
def get_soup(markup: Union[str, bytes]) -> BeautifulSoup:
|
|
13
|
+
return BeautifulSoup(markup, "html.parser")
|
|
14
14
|
|
|
15
15
|
@staticmethod
|
|
16
16
|
def create_test_user():
|
wagtail/tests/test_blocks.py
CHANGED
|
@@ -50,6 +50,13 @@ class ContextCharBlock(blocks.CharBlock):
|
|
|
50
50
|
return super(blocks.CharBlock, self).get_context(value, parent_context)
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
class TestBlock(SimpleTestCase):
|
|
54
|
+
def test_normalize(self):
|
|
55
|
+
"""The base normalize implementation should return its argument unchanged"""
|
|
56
|
+
obj = object()
|
|
57
|
+
self.assertIs(blocks.Block().normalize(obj), obj)
|
|
58
|
+
|
|
59
|
+
|
|
53
60
|
class TestFieldBlock(WagtailTestUtils, SimpleTestCase):
|
|
54
61
|
def test_charfield_render(self):
|
|
55
62
|
block = blocks.CharBlock()
|
|
@@ -206,7 +213,8 @@ class TestFieldBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
206
213
|
def test_form_handling_is_independent_of_serialisation(self):
|
|
207
214
|
class Base64EncodingCharBlock(blocks.CharBlock):
|
|
208
215
|
"""A CharBlock with a deliberately perverse JSON (de)serialisation format
|
|
209
|
-
so that it visibly blows up if we call to_python / get_prep_value where we shouldn't
|
|
216
|
+
so that it visibly blows up if we call to_python / get_prep_value where we shouldn't
|
|
217
|
+
"""
|
|
210
218
|
|
|
211
219
|
def to_python(self, jsonish_value):
|
|
212
220
|
# decode as base64 on the way out of the JSON serialisation
|
|
@@ -718,6 +726,14 @@ class TestRichTextBlock(TestCase):
|
|
|
718
726
|
|
|
719
727
|
self.assertEqual(list(block.extract_references(value)), [(Page, "1", "", "")])
|
|
720
728
|
|
|
729
|
+
def test_normalize(self):
|
|
730
|
+
block = blocks.RichTextBlock()
|
|
731
|
+
for value in ("Hello, world", RichText("Hello, world")):
|
|
732
|
+
with self.subTest(value=value):
|
|
733
|
+
normalized = block.normalize(value)
|
|
734
|
+
self.assertIsInstance(normalized, RichText)
|
|
735
|
+
self.assertEqual(normalized.source, "Hello, world")
|
|
736
|
+
|
|
721
737
|
|
|
722
738
|
class TestChoiceBlock(WagtailTestUtils, SimpleTestCase):
|
|
723
739
|
def setUp(self):
|
|
@@ -2256,6 +2272,53 @@ class TestStructBlock(SimpleTestCase):
|
|
|
2256
2272
|
self.assertIs(value.block, copied.block)
|
|
2257
2273
|
self.assertEqual(value, copied)
|
|
2258
2274
|
|
|
2275
|
+
def test_normalize_base_cases(self):
|
|
2276
|
+
"""Test the trivially recursive and already normalized cases"""
|
|
2277
|
+
block = blocks.StructBlock([("title", blocks.CharBlock())])
|
|
2278
|
+
self.assertEqual(
|
|
2279
|
+
block.normalize({"title": "Foo"}), block._to_struct_value({"title": "Foo"})
|
|
2280
|
+
)
|
|
2281
|
+
self.assertEqual(
|
|
2282
|
+
block.normalize(block._to_struct_value({"title": "Foo"})),
|
|
2283
|
+
block._to_struct_value({"title": "Foo"}),
|
|
2284
|
+
)
|
|
2285
|
+
|
|
2286
|
+
def test_recursive_normalize(self):
|
|
2287
|
+
"""StructBlock.normalize should recursively normalize all children"""
|
|
2288
|
+
|
|
2289
|
+
block = blocks.StructBlock(
|
|
2290
|
+
[
|
|
2291
|
+
(
|
|
2292
|
+
"inner_stream",
|
|
2293
|
+
blocks.StreamBlock(
|
|
2294
|
+
[
|
|
2295
|
+
("inner_char", blocks.CharBlock()),
|
|
2296
|
+
("inner_int", blocks.IntegerBlock()),
|
|
2297
|
+
]
|
|
2298
|
+
),
|
|
2299
|
+
),
|
|
2300
|
+
("list_of_ints", blocks.ListBlock(blocks.IntegerBlock())),
|
|
2301
|
+
]
|
|
2302
|
+
)
|
|
2303
|
+
|
|
2304
|
+
# A value in the human friendly format
|
|
2305
|
+
value = {
|
|
2306
|
+
"inner_stream": [("inner_char", "Hello, world"), ("inner_int", 42)],
|
|
2307
|
+
"list_of_ints": [5, 6, 7, 8],
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
normalized = block.normalize(value)
|
|
2311
|
+
self.assertIsInstance(normalized, blocks.StructValue)
|
|
2312
|
+
self.assertIsInstance(normalized["inner_stream"], blocks.StreamValue)
|
|
2313
|
+
self.assertIsInstance(
|
|
2314
|
+
normalized["inner_stream"][0], blocks.StreamValue.StreamChild
|
|
2315
|
+
)
|
|
2316
|
+
self.assertIsInstance(
|
|
2317
|
+
normalized["inner_stream"][1], blocks.StreamValue.StreamChild
|
|
2318
|
+
)
|
|
2319
|
+
self.assertIsInstance(normalized["list_of_ints"], blocks.list_block.ListValue)
|
|
2320
|
+
self.assertIsInstance(normalized["list_of_ints"][0], int)
|
|
2321
|
+
|
|
2259
2322
|
|
|
2260
2323
|
class TestStructBlockWithCustomStructValue(SimpleTestCase):
|
|
2261
2324
|
def test_initialisation(self):
|
|
@@ -2433,8 +2496,50 @@ class TestStructBlockWithCustomStructValue(SimpleTestCase):
|
|
|
2433
2496
|
html = block.render(struct_value)
|
|
2434
2497
|
self.assertEqual(html, "<div>EMPTY TITLE</div>\n")
|
|
2435
2498
|
|
|
2499
|
+
def test_normalize(self):
|
|
2500
|
+
"""A normalized StructBlock value should be an instance of the StructBlock's value_class"""
|
|
2501
|
+
|
|
2502
|
+
class CustomStructValue(blocks.StructValue):
|
|
2503
|
+
pass
|
|
2504
|
+
|
|
2505
|
+
class CustomStructBlock(blocks.StructBlock):
|
|
2506
|
+
text = blocks.TextBlock()
|
|
2507
|
+
|
|
2508
|
+
class Meta:
|
|
2509
|
+
value_class = CustomStructValue
|
|
2510
|
+
|
|
2511
|
+
self.assertIsInstance(
|
|
2512
|
+
CustomStructBlock().normalize({"text": "She sells sea shells"}),
|
|
2513
|
+
CustomStructValue,
|
|
2514
|
+
)
|
|
2515
|
+
|
|
2516
|
+
def test_normalize_incorrect_value_class(self):
|
|
2517
|
+
"""
|
|
2518
|
+
If StructBlock.normalize is passed a StructValue instance that doesn't
|
|
2519
|
+
match the StructBlock's `value_class', it should convert the value
|
|
2520
|
+
to the correct class.
|
|
2521
|
+
"""
|
|
2522
|
+
|
|
2523
|
+
class CustomStructValue(blocks.StructValue):
|
|
2524
|
+
pass
|
|
2525
|
+
|
|
2526
|
+
class CustomStructBlock(blocks.StructBlock):
|
|
2527
|
+
text = blocks.TextBlock()
|
|
2528
|
+
|
|
2529
|
+
class Meta:
|
|
2530
|
+
value_class = CustomStructValue
|
|
2531
|
+
|
|
2532
|
+
block = CustomStructBlock()
|
|
2533
|
+
# Not an instance of CustomStructValue, which CustomStructBlock uses.
|
|
2534
|
+
value = blocks.StructValue(block, {"text": "The quick brown fox"})
|
|
2535
|
+
self.assertIsInstance(block.normalize(value), CustomStructValue)
|
|
2536
|
+
|
|
2436
2537
|
|
|
2437
2538
|
class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
2539
|
+
def assert_eq_list_values(self, p, q):
|
|
2540
|
+
# We can't directly compare ListValue instances yet
|
|
2541
|
+
self.assertEqual(list(p), list(q))
|
|
2542
|
+
|
|
2438
2543
|
def test_initialise_with_class(self):
|
|
2439
2544
|
block = blocks.ListBlock(blocks.CharBlock)
|
|
2440
2545
|
|
|
@@ -2961,6 +3066,42 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
2961
3066
|
self.assertEqual(len(result[0]["value"]), 2)
|
|
2962
3067
|
self.assertEqual(result[0]["value"][0]["value"], "foo")
|
|
2963
3068
|
|
|
3069
|
+
def test_normalize_base_case(self):
|
|
3070
|
+
"""Test normalize when trivially recursive, or already a ListValue"""
|
|
3071
|
+
block = blocks.ListBlock(blocks.IntegerBlock)
|
|
3072
|
+
normalized = block.normalize([0, 1, 1, 2, 3])
|
|
3073
|
+
self.assertIsInstance(normalized, blocks.list_block.ListValue)
|
|
3074
|
+
self.assert_eq_list_values(normalized, [0, 1, 1, 2, 3])
|
|
3075
|
+
|
|
3076
|
+
normalized = block.normalize(
|
|
3077
|
+
blocks.list_block.ListValue(block, [0, 1, 1, 2, 3])
|
|
3078
|
+
)
|
|
3079
|
+
self.assertIsInstance(normalized, blocks.list_block.ListValue)
|
|
3080
|
+
self.assert_eq_list_values(normalized, [0, 1, 1, 2, 3])
|
|
3081
|
+
|
|
3082
|
+
def test_normalize_empty(self):
|
|
3083
|
+
block = blocks.ListBlock(blocks.IntegerBlock())
|
|
3084
|
+
normalized = block.normalize([])
|
|
3085
|
+
self.assertIsInstance(normalized, blocks.list_block.ListValue)
|
|
3086
|
+
self.assert_eq_list_values(normalized, [])
|
|
3087
|
+
|
|
3088
|
+
def test_recursive_normalize(self):
|
|
3089
|
+
"""
|
|
3090
|
+
ListBlock.normalize should recursively normalize all values passed to
|
|
3091
|
+
it, and return a ListValue.
|
|
3092
|
+
"""
|
|
3093
|
+
inner_list_block = blocks.ListBlock(blocks.IntegerBlock())
|
|
3094
|
+
block = blocks.ListBlock(inner_list_block)
|
|
3095
|
+
values = [
|
|
3096
|
+
[[1, 2, 3]],
|
|
3097
|
+
[blocks.list_block.ListValue(block, [1, 2, 3])],
|
|
3098
|
+
]
|
|
3099
|
+
|
|
3100
|
+
for value in values:
|
|
3101
|
+
normalized = block.normalize(value)
|
|
3102
|
+
self.assertIsInstance(normalized, blocks.list_block.ListValue)
|
|
3103
|
+
self.assert_eq_list_values(normalized[0], [1, 2, 3])
|
|
3104
|
+
|
|
2964
3105
|
|
|
2965
3106
|
class TestListBlockWithFixtures(TestCase):
|
|
2966
3107
|
fixtures = ["test.json"]
|
|
@@ -4228,6 +4369,120 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
|
|
4228
4369
|
)
|
|
4229
4370
|
|
|
4230
4371
|
|
|
4372
|
+
class TestNormalizeStreamBlock(SimpleTestCase):
|
|
4373
|
+
@classmethod
|
|
4374
|
+
def setUpClass(cls):
|
|
4375
|
+
super().setUpClass()
|
|
4376
|
+
cls.simple_block = blocks.StreamBlock(
|
|
4377
|
+
[("number", blocks.IntegerBlock()), ("text", blocks.TextBlock())]
|
|
4378
|
+
)
|
|
4379
|
+
cls.recursive_block = blocks.StreamBlock(
|
|
4380
|
+
[
|
|
4381
|
+
(
|
|
4382
|
+
"inner_stream",
|
|
4383
|
+
blocks.StreamBlock(
|
|
4384
|
+
[
|
|
4385
|
+
("number", blocks.IntegerBlock()),
|
|
4386
|
+
("text", blocks.TextBlock()),
|
|
4387
|
+
("inner_list", blocks.ListBlock(blocks.IntegerBlock)),
|
|
4388
|
+
]
|
|
4389
|
+
),
|
|
4390
|
+
),
|
|
4391
|
+
("struct", blocks.StructBlock([("bool", blocks.BooleanBlock())])),
|
|
4392
|
+
("list", blocks.ListBlock(blocks.IntegerBlock)),
|
|
4393
|
+
]
|
|
4394
|
+
)
|
|
4395
|
+
|
|
4396
|
+
def test_normalize_empty_stream(self):
|
|
4397
|
+
values = [[], "", None]
|
|
4398
|
+
for value in values:
|
|
4399
|
+
with self.subTest(value=value):
|
|
4400
|
+
self.assertEqual(
|
|
4401
|
+
self.simple_block.normalize(value),
|
|
4402
|
+
blocks.StreamValue(self.simple_block, []),
|
|
4403
|
+
)
|
|
4404
|
+
|
|
4405
|
+
def test_normalize_base_case(self):
|
|
4406
|
+
"""
|
|
4407
|
+
Test normalize when trivially recursive, or already a StreamValue
|
|
4408
|
+
"""
|
|
4409
|
+
value = [("number", 1), ("text", "ichiban")]
|
|
4410
|
+
stream_value = blocks.StreamValue(self.simple_block, value)
|
|
4411
|
+
self.assertEqual(stream_value, self.simple_block.normalize(value))
|
|
4412
|
+
self.assertEqual(stream_value, self.simple_block.normalize(stream_value))
|
|
4413
|
+
|
|
4414
|
+
def test_normalize_recursive(self):
|
|
4415
|
+
"""
|
|
4416
|
+
A stream block is normalized iff all of its sub-blocks are normalized.
|
|
4417
|
+
"""
|
|
4418
|
+
values = (
|
|
4419
|
+
# A smart, "list of tuples" representation
|
|
4420
|
+
[
|
|
4421
|
+
("struct", {"bool": True}),
|
|
4422
|
+
(
|
|
4423
|
+
"inner_stream",
|
|
4424
|
+
[
|
|
4425
|
+
("number", 1),
|
|
4426
|
+
("text", "one"),
|
|
4427
|
+
("inner_list", [0, 1, 1, 2, 3, 5]),
|
|
4428
|
+
],
|
|
4429
|
+
),
|
|
4430
|
+
("list", [0, 1, 1, 2, 3, 5]),
|
|
4431
|
+
],
|
|
4432
|
+
# A json-ish representation - the serialized format
|
|
4433
|
+
[
|
|
4434
|
+
{"type": "struct", "value": {"bool": True}},
|
|
4435
|
+
{
|
|
4436
|
+
"type": "inner_stream",
|
|
4437
|
+
"value": [
|
|
4438
|
+
{"type": "number", "value": 1},
|
|
4439
|
+
{"type": "text", "value": "one"},
|
|
4440
|
+
{
|
|
4441
|
+
"type": "inner_list",
|
|
4442
|
+
"value": [
|
|
4443
|
+
# Unlike StreamBlock, ListBlock requires that its items
|
|
4444
|
+
# have IDs, to distinguish the new serialization format
|
|
4445
|
+
# from the old.
|
|
4446
|
+
{"type": "item", "value": 0, "id": 1},
|
|
4447
|
+
{"type": "item", "value": 1, "id": 2},
|
|
4448
|
+
{"type": "item", "value": 2, "id": 3},
|
|
4449
|
+
],
|
|
4450
|
+
},
|
|
4451
|
+
],
|
|
4452
|
+
},
|
|
4453
|
+
{
|
|
4454
|
+
"type": "list",
|
|
4455
|
+
"value": [
|
|
4456
|
+
{"type": "item", "value": 0, "id": 1},
|
|
4457
|
+
{"type": "item", "value": 1, "id": 2},
|
|
4458
|
+
{"type": "item", "value": 2, "id": 3},
|
|
4459
|
+
],
|
|
4460
|
+
},
|
|
4461
|
+
],
|
|
4462
|
+
)
|
|
4463
|
+
|
|
4464
|
+
for value in values:
|
|
4465
|
+
with self.subTest(value=value):
|
|
4466
|
+
# Normalize the value.
|
|
4467
|
+
normalized = self.recursive_block.normalize(value)
|
|
4468
|
+
# Then check all of the sub-blocks have been normalized:
|
|
4469
|
+
# the StructBlock child
|
|
4470
|
+
self.assertIsInstance(normalized[0].value, blocks.StructValue)
|
|
4471
|
+
self.assertIsInstance(normalized[0].value["bool"], bool)
|
|
4472
|
+
# the nested StreamBlock child
|
|
4473
|
+
self.assertIsInstance(normalized[1].value, blocks.StreamValue)
|
|
4474
|
+
self.assertIsInstance(normalized[1].value[0].value, int)
|
|
4475
|
+
self.assertIsInstance(normalized[1].value[1].value, str)
|
|
4476
|
+
# the ListBlock child
|
|
4477
|
+
self.assertIsInstance(normalized[2].value[0], int)
|
|
4478
|
+
self.assertIsInstance(normalized[2].value, blocks.list_block.ListValue)
|
|
4479
|
+
# the inner ListBlock nested in the nested streamblock
|
|
4480
|
+
self.assertIsInstance(normalized[1].value[2].value[0], int)
|
|
4481
|
+
self.assertIsInstance(
|
|
4482
|
+
normalized[1].value[2].value, blocks.list_block.ListValue
|
|
4483
|
+
)
|
|
4484
|
+
|
|
4485
|
+
|
|
4231
4486
|
class TestStructBlockWithFixtures(TestCase):
|
|
4232
4487
|
fixtures = ["test.json"]
|
|
4233
4488
|
|
|
@@ -4742,6 +4997,12 @@ class TestStaticBlock(unittest.TestCase):
|
|
|
4742
4997
|
result = block.to_python(None)
|
|
4743
4998
|
self.assertIsNone(result)
|
|
4744
4999
|
|
|
5000
|
+
def test_normalize(self):
|
|
5001
|
+
"""
|
|
5002
|
+
StaticBlock.normalize always returns None, as a StaticBlock has no value
|
|
5003
|
+
"""
|
|
5004
|
+
self.assertIsNone(blocks.StaticBlock().normalize(11))
|
|
5005
|
+
|
|
4745
5006
|
|
|
4746
5007
|
class TestDateBlock(TestCase):
|
|
4747
5008
|
def test_adapt(self):
|
wagtail/tests/test_migrations.py
CHANGED
|
@@ -16,7 +16,7 @@ class TestForMigrations(TestCase):
|
|
|
16
16
|
app_labels = {
|
|
17
17
|
app.label
|
|
18
18
|
for app in apps.get_app_configs()
|
|
19
|
-
if app.name.
|
|
19
|
+
if app.name.split(".")[0] == "wagtail"
|
|
20
20
|
}
|
|
21
21
|
for app_label in app_labels:
|
|
22
22
|
apps.get_app_config(app_label.split(".")[-1])
|
wagtail/tests/test_page_model.py
CHANGED
|
@@ -68,6 +68,7 @@ from wagtail.test.testapp.models import (
|
|
|
68
68
|
TaggedPage,
|
|
69
69
|
)
|
|
70
70
|
from wagtail.test.utils import WagtailTestUtils
|
|
71
|
+
from wagtail.url_routing import RouteResult
|
|
71
72
|
|
|
72
73
|
|
|
73
74
|
def get_ct(model):
|
|
@@ -211,6 +212,50 @@ class TestSiteRouting(TestCase):
|
|
|
211
212
|
self.unrecognised_port = "8000"
|
|
212
213
|
self.unrecognised_hostname = "unknown.site.com"
|
|
213
214
|
|
|
215
|
+
def test_route_for_request_query_count(self):
|
|
216
|
+
request = get_dummy_request(site=self.events_site)
|
|
217
|
+
with self.assertNumQueries(2):
|
|
218
|
+
# expect queries for site & page
|
|
219
|
+
Page.route_for_request(request, request.path)
|
|
220
|
+
with self.assertNumQueries(0):
|
|
221
|
+
# subsequent lookups should be cached on the request
|
|
222
|
+
Page.route_for_request(request, request.path)
|
|
223
|
+
|
|
224
|
+
def test_route_for_request_value(self):
|
|
225
|
+
request = get_dummy_request(site=self.events_site)
|
|
226
|
+
self.assertFalse(hasattr(request, "_wagtail_route_for_request"))
|
|
227
|
+
result = Page.route_for_request(request, request.path)
|
|
228
|
+
self.assertTrue(isinstance(result, RouteResult))
|
|
229
|
+
self.assertEqual(
|
|
230
|
+
(result[0], result[1], result[2]),
|
|
231
|
+
(self.events_site.root_page.specific, [], {}),
|
|
232
|
+
)
|
|
233
|
+
self.assertTrue(hasattr(request, "_wagtail_route_for_request"))
|
|
234
|
+
self.assertIs(request._wagtail_route_for_request, result)
|
|
235
|
+
|
|
236
|
+
def test_route_for_request_cached(self):
|
|
237
|
+
request = get_dummy_request(site=self.events_site)
|
|
238
|
+
m = Mock()
|
|
239
|
+
request._wagtail_route_for_request = m
|
|
240
|
+
with self.assertNumQueries(0):
|
|
241
|
+
self.assertEqual(Page.route_for_request(request, request.path), m)
|
|
242
|
+
|
|
243
|
+
def test_route_for_request_suppresses_404(self):
|
|
244
|
+
request = get_dummy_request(path="does-not-exist", site=self.events_site)
|
|
245
|
+
self.assertIsNone(Page.route_for_request(request, request.path))
|
|
246
|
+
|
|
247
|
+
def test_find_for_request(self):
|
|
248
|
+
request_200 = get_dummy_request(site=self.events_site)
|
|
249
|
+
self.assertEqual(
|
|
250
|
+
Page.find_for_request(request_200, request_200.path),
|
|
251
|
+
self.events_site.root_page.specific,
|
|
252
|
+
)
|
|
253
|
+
request_404 = get_dummy_request(path="does-not-exist", site=self.events_site)
|
|
254
|
+
self.assertEqual(
|
|
255
|
+
Page.find_for_request(request_404, request_404.path),
|
|
256
|
+
None,
|
|
257
|
+
)
|
|
258
|
+
|
|
214
259
|
def test_valid_headers_route_to_specific_site(self):
|
|
215
260
|
# requests with a known Host: header should be directed to the specific site
|
|
216
261
|
request = get_dummy_request(site=self.events_site)
|
|
@@ -502,6 +547,20 @@ class TestRouting(TestCase):
|
|
|
502
547
|
christmas_page.get_url(request=request), "/events/christmas/"
|
|
503
548
|
)
|
|
504
549
|
|
|
550
|
+
def test_cached_parent_obj_set(self):
|
|
551
|
+
homepage = Page.objects.get(url_path="/home/")
|
|
552
|
+
christmas_page = EventPage.objects.get(url_path="/home/events/christmas/")
|
|
553
|
+
|
|
554
|
+
request = get_dummy_request(path="/events/christmas/")
|
|
555
|
+
(found_page, args, kwargs) = homepage.route(request, ["events", "christmas"])
|
|
556
|
+
self.assertEqual(found_page, christmas_page)
|
|
557
|
+
|
|
558
|
+
# parent cache should be set
|
|
559
|
+
events_page = Page.objects.get(url_path="/home/events/").specific
|
|
560
|
+
with self.assertNumQueries(0):
|
|
561
|
+
parent = found_page.get_parent(update=False)
|
|
562
|
+
self.assertEqual(parent, events_page)
|
|
563
|
+
|
|
505
564
|
|
|
506
565
|
@override_settings(
|
|
507
566
|
ROOT_URLCONF="wagtail.test.urls_multilang",
|
|
@@ -3917,3 +3976,21 @@ class TestPageCacheKey(TestCase):
|
|
|
3917
3976
|
self.page.slug = "something-else"
|
|
3918
3977
|
self.page.save()
|
|
3919
3978
|
self.assertNotEqual(self.page.cache_key, original_cache_key)
|
|
3979
|
+
|
|
3980
|
+
|
|
3981
|
+
class TestPageCachedParentObjExists(TestCase):
|
|
3982
|
+
fixtures = ["test.json"]
|
|
3983
|
+
|
|
3984
|
+
def test_cached_parent_obj_exists(self):
|
|
3985
|
+
# https://github.com/wagtail/wagtail/pull/11737
|
|
3986
|
+
|
|
3987
|
+
# Test if _cached_parent_obj is set after using page.get_parent()
|
|
3988
|
+
# This is treebeard specific, we don't know if their API will change.
|
|
3989
|
+
homepage = Page.objects.get(url_path="/home/")
|
|
3990
|
+
homepage._cached_parent_obj = "_cached_parent_obj_exists"
|
|
3991
|
+
parent = homepage.get_parent(update=False)
|
|
3992
|
+
self.assertEqual(
|
|
3993
|
+
parent,
|
|
3994
|
+
"_cached_parent_obj_exists",
|
|
3995
|
+
"Page.get_parent() (treebeard) no longer uses _cached_parent_obj to cache the parent object",
|
|
3996
|
+
)
|