wagtail 7.1.2__py3-none-any.whl → 7.2rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wagtail/__init__.py +1 -1
- wagtail/actions/copy_page.py +1 -1
- wagtail/actions/create_alias.py +1 -1
- wagtail/actions/delete_page.py +1 -1
- wagtail/actions/publish_page_revision.py +1 -1
- wagtail/actions/publish_revision.py +1 -1
- wagtail/actions/revert_to_page_revision.py +1 -1
- wagtail/actions/unpublish.py +1 -1
- wagtail/actions/unpublish_page.py +1 -1
- wagtail/admin/auth.py +3 -1
- wagtail/admin/checks.py +2 -2
- wagtail/admin/filters.py +28 -1
- wagtail/admin/forms/collections.py +1 -1
- wagtail/admin/forms/comments.py +1 -1
- wagtail/admin/forms/models.py +1 -1
- wagtail/admin/forms/pages.py +1 -1
- wagtail/admin/forms/tags.py +1 -1
- wagtail/admin/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/cs/LC_MESSAGES/django.po +25 -1
- wagtail/admin/locale/en/LC_MESSAGES/django.po +278 -192
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +29 -15
- wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/django.po +3 -2
- wagtail/admin/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/nl/LC_MESSAGES/django.po +57 -3
- wagtail/admin/locale/nl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/nl/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ru/LC_MESSAGES/django.po +58 -1
- wagtail/admin/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/tr/LC_MESSAGES/django.po +3 -2
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- 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 +2 -2
- 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/filtered-select.js +1 -1
- wagtail/admin/static/wagtailadmin/js/icons.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/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/userbar.js.LICENSE.txt +2 -2
- wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-transition.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery-3.6.0.min.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery-ui-1.13.2.min.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.datetimepicker.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload-process.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.iframe-transport.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/tag-it.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +1 -1
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/templates/wagtailadmin/account/account.html +2 -0
- wagtail/admin/templates/wagtailadmin/base.html +14 -0
- wagtail/admin/templates/wagtailadmin/generic/chooser/chooser.html +2 -1
- wagtail/admin/templates/wagtailadmin/generic/chooser/creation_form.html +2 -1
- wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
- wagtail/admin/templates/wagtailadmin/panels/object_list.html +1 -1
- wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +3 -2
- wagtail/admin/templates/wagtailadmin/shared/formatted_field.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +19 -0
- wagtail/admin/templates/wagtailadmin/shared/panel.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/set_privacy.html +15 -0
- wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +28 -1
- wagtail/admin/templates/wagtailadmin/shared/workflow_history/detail.html +2 -2
- wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_header.html → tables/ordering_header.html} +2 -2
- wagtail/admin/templates/wagtailadmin/tables/title_cell.html +1 -1
- wagtail/admin/templates/wagtailadmin/widgets/{daterange_input.html → range_input.html} +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/task_chooser/chooser.html +4 -2
- wagtail/admin/templatetags/wagtailadmin_tags.py +41 -22
- wagtail/admin/tests/api/test_pages.py +7 -7
- wagtail/admin/tests/api/test_renderer_classes.py +16 -0
- wagtail/admin/tests/pages/test_create_page.py +34 -2
- wagtail/admin/tests/pages/test_edit_page.py +128 -14
- wagtail/admin/tests/pages/test_explorer_view.py +34 -7
- wagtail/admin/tests/pages/test_reorder_page.py +11 -0
- wagtail/admin/tests/test_collections_views.py +12 -0
- wagtail/admin/tests/test_edit_handlers.py +3 -3
- wagtail/admin/tests/test_filters.py +2 -2
- wagtail/admin/tests/test_keyboard_shortcuts.py +52 -2
- wagtail/admin/tests/test_menu.py +0 -2
- wagtail/admin/tests/test_privacy.py +16 -16
- wagtail/admin/tests/test_templatetags.py +137 -0
- wagtail/admin/tests/test_workflows.py +34 -0
- wagtail/admin/tests/viewsets/test_model_viewset.py +322 -0
- wagtail/admin/ui/tables/orderable.py +73 -0
- wagtail/admin/ui/tables/pages.py +3 -13
- wagtail/admin/views/collection_privacy.py +6 -2
- wagtail/admin/views/generic/__init__.py +1 -0
- wagtail/admin/views/generic/mixins.py +20 -2
- wagtail/admin/views/generic/models.py +67 -1
- wagtail/admin/views/generic/ordering.py +79 -0
- wagtail/admin/views/home.py +3 -3
- wagtail/admin/views/page_privacy.py +5 -2
- wagtail/admin/views/pages/create.py +1 -1
- wagtail/admin/views/pages/edit.py +2 -2
- wagtail/admin/views/pages/listing.py +7 -42
- wagtail/admin/views/pages/move.py +1 -1
- wagtail/admin/views/pages/ordering.py +1 -1
- wagtail/admin/viewsets/base.py +1 -1
- wagtail/admin/viewsets/model.py +49 -1
- wagtail/admin/wagtail_hooks.py +2 -1
- wagtail/admin/widgets/slug.py +10 -10
- wagtail/api/v2/serializers.py +1 -1
- wagtail/api/v2/tests/test_renderer_classes.py +32 -0
- wagtail/apps.py +2 -0
- wagtail/bin/wagtail.py +1 -1
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +14 -14
- wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.po +19 -2
- wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.po +18 -1
- wagtail/contrib/frontend_cache/tests.py +4 -2
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +4 -4
- wagtail/contrib/redirects/tests/test_tmp_storages.py +20 -0
- wagtail/contrib/redirects/tmp_storages.py +1 -1
- wagtail/contrib/redirects/views.py +3 -3
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.po +43 -3
- wagtail/contrib/search_promotions/static/wagtailsearchpromotions/js/query-chooser-modal.js +1 -1
- wagtail/contrib/search_promotions/views/settings.py +2 -2
- wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.po +6 -2
- wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/tests/site_specific/test_admin.py +40 -6
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/templates/wagtailstyleguide/base.html +5 -5
- wagtail/contrib/table_block/blocks.py +1 -0
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +5 -1
- wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/coreutils.py +5 -5
- wagtail/documents/forms.py +18 -1
- wagtail/documents/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/documents/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/nl/LC_MESSAGES/django.po +9 -0
- wagtail/documents/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ru/LC_MESSAGES/django.po +9 -0
- wagtail/documents/models.py +1 -1
- wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
- 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/add.html +0 -34
- wagtail/documents/tests/test_admin_views.py +132 -26
- wagtail/documents/tests/test_collection_privacy.py +18 -4
- wagtail/documents/tests/test_form_overrides.py +1 -1
- wagtail/documents/tests/test_search.py +21 -8
- wagtail/documents/views/documents.py +1 -1
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/static/wagtailembeds/js/embed-chooser-modal.js +1 -1
- wagtail/images/forms.py +16 -1
- wagtail/images/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/cs/LC_MESSAGES/django.po +12 -1
- wagtail/images/locale/en/LC_MESSAGES/django.po +57 -46
- wagtail/images/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/nl/LC_MESSAGES/django.po +37 -14
- wagtail/images/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ru/LC_MESSAGES/django.po +20 -1
- wagtail/images/models.py +1 -1
- wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
- wagtail/images/static/wagtailimages/js/focal-point-chooser.js +1 -1
- wagtail/images/static/wagtailimages/js/image-block.js +1 -1
- 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/static/wagtailimages/js/image-url-generator.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.Jcrop.min.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-image.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-validate.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/load-image.min.js +1 -1
- wagtail/images/templates/wagtailimages/chooser/chooser.html +22 -13
- wagtail/images/templates/wagtailimages/chooser/image_preview_column_cell.html +10 -0
- wagtail/images/templates/wagtailimages/chooser/results.html +24 -20
- wagtail/images/templates/wagtailimages/chooser/title_column_cell.html +15 -0
- wagtail/images/templates/wagtailimages/images/add.html +0 -34
- wagtail/images/templates/wagtailimages/images/index.html +3 -3
- wagtail/images/templates/wagtailimages/images/index_results.html +1 -1
- wagtail/images/templates/wagtailimages/images/layout_toggle_button.html +8 -7
- wagtail/images/templatetags/wagtailimages_tags.py +2 -2
- wagtail/images/tests/test_admin_views.py +87 -0
- wagtail/images/tests/test_form_overrides.py +1 -1
- wagtail/images/tests/test_models.py +48 -9
- wagtail/images/views/chooser.py +66 -2
- wagtail/locale/en/LC_MESSAGES/django.po +55 -55
- wagtail/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/is_IS/LC_MESSAGES/django.po +3 -3
- wagtail/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/nl/LC_MESSAGES/django.po +11 -2
- wagtail/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ru/LC_MESSAGES/django.po +11 -1
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/nl/LC_MESSAGES/django.po +12 -1
- wagtail/locales/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/ru/LC_MESSAGES/django.po +10 -1
- wagtail/locales/views.py +2 -2
- wagtail/models/orderable.py +10 -0
- wagtail/models/pages.py +9 -11
- wagtail/models/sites.py +1 -1
- wagtail/models/workflows.py +8 -5
- wagtail/project_template/home/tests.py +6 -7
- wagtail/project_template/project_name/settings/base.py +9 -9
- wagtail/project_template/requirements.txt +1 -1
- wagtail/query.py +7 -2
- wagtail/rich_text/rewriters.py +1 -1
- wagtail/search/apps.py +4 -49
- wagtail/search/backends/__init__.py +1 -113
- wagtail/search/backends/base.py +1 -547
- wagtail/search/backends/database/__init__.py +1 -50
- wagtail/search/backends/database/fallback.py +1 -253
- wagtail/search/backends/database/mysql/mysql.py +1 -700
- wagtail/search/backends/database/mysql/query.py +1 -258
- wagtail/search/backends/database/postgres/postgres.py +1 -749
- wagtail/search/backends/database/postgres/query.py +1 -83
- wagtail/search/backends/database/postgres/weights.py +1 -63
- wagtail/search/backends/database/sqlite/query.py +1 -294
- wagtail/search/backends/database/sqlite/sqlite.py +1 -719
- wagtail/search/backends/database/sqlite/utils.py +1 -35
- wagtail/search/backends/deprecation.py +45 -0
- wagtail/search/backends/elasticsearch7.py +18 -1260
- wagtail/search/backends/elasticsearch8.py +21 -96
- wagtail/search/backends/elasticsearch9.py +35 -0
- wagtail/search/backends/opensearch2.py +35 -0
- wagtail/search/backends/opensearch3.py +35 -0
- wagtail/search/index.py +1 -358
- wagtail/search/locale/en/LC_MESSAGES/django.po +2 -10
- wagtail/search/management/commands/update_index.py +1 -205
- wagtail/search/management/commands/wagtail_update_index.py +1 -4
- wagtail/search/models.py +32 -158
- wagtail/search/query.py +1 -114
- wagtail/search/queryset.py +1 -43
- wagtail/search/signal_handlers.py +1 -24
- wagtail/search/tasks.py +1 -10
- wagtail/search/tests/test_elasticsearch.py +22 -0
- wagtail/search/utils.py +1 -206
- wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/snippets/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/ru/LC_MESSAGES/django.po +8 -1
- wagtail/snippets/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/tr/LC_MESSAGES/django.po +8 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
- wagtail/snippets/tests/test_reordering.py +319 -0
- wagtail/snippets/tests/test_snippets.py +65 -12
- wagtail/snippets/views/snippets.py +16 -0
- wagtail/test/numberformat.py +30 -0
- wagtail/test/settings.py +35 -12
- wagtail/test/testapp/fields.py +12 -0
- wagtail/test/testapp/migrations/0056_commentablejsonpage.py +50 -0
- wagtail/test/testapp/migrations/0057_featurecompletetoy_sort_order.py +23 -0
- wagtail/test/testapp/migrations/0058_customlocktask.py +31 -0
- wagtail/test/testapp/models.py +27 -0
- wagtail/test/testapp/views.py +3 -1
- wagtail/test/utils/page_tests.py +17 -17
- wagtail/test/utils/template_tests.py +4 -6
- wagtail/test/utils/wagtail_tests.py +1 -2
- wagtail/tests/test_page_model.py +15 -0
- wagtail/{search/tests → tests}/test_page_search.py +29 -2
- wagtail/tests/test_search_fields.py +69 -0
- wagtail/tests/test_tests.py +62 -6
- wagtail/tests/test_workflow.py +25 -1
- wagtail/users/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/cs/LC_MESSAGES/django.po +3 -0
- wagtail/users/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/nl/LC_MESSAGES/django.po +6 -3
- wagtail/users/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/ru/LC_MESSAGES/django.po +5 -1
- wagtail/users/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/tr/LC_MESSAGES/django.po +78 -4
- wagtail/users/templates/wagtailusers/users/create.html +2 -0
- wagtail/users/templates/wagtailusers/users/edit.html +2 -0
- wagtail/users/tests/test_admin_views.py +4 -0
- wagtail/users/views/users.py +1 -1
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/METADATA +7 -6
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/RECORD +309 -315
- wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +0 -13
- wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +0 -13
- wagtail/search/tests/__init__.py +0 -0
- wagtail/search/tests/elasticsearch_common_tests.py +0 -251
- wagtail/search/tests/test_backends.py +0 -1215
- wagtail/search/tests/test_db_backend.py +0 -62
- wagtail/search/tests/test_elasticsearch7_backend.py +0 -1452
- wagtail/search/tests/test_elasticsearch8_backend.py +0 -15
- wagtail/search/tests/test_index_functions.py +0 -256
- wagtail/search/tests/test_indexed_class.py +0 -157
- wagtail/search/tests/test_mysql_backend.py +0 -192
- wagtail/search/tests/test_postgres_backend.py +0 -210
- wagtail/search/tests/test_queries.py +0 -332
- wagtail/search/tests/test_related_fields.py +0 -102
- wagtail/search/tests/test_sqlite_backend.py +0 -52
- wagtail/test/search/__init__.py +0 -0
- wagtail/test/search/apps.py +0 -9
- wagtail/test/search/fixtures/search.json +0 -545
- wagtail/test/search/migrations/0001_initial.py +0 -146
- wagtail/test/search/migrations/0002_bookunindexed.py +0 -43
- wagtail/test/search/migrations/0003_book_summary.py +0 -18
- wagtail/test/search/migrations/__init__.py +0 -0
- wagtail/test/search/models.py +0 -137
- /wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_cell.html → tables/ordering_cell.html} +0 -0
- /wagtail/{search/checks.py → checks.py} +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/WHEEL +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/licenses/LICENSE +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/top_level.txt +0 -0
|
@@ -999,12 +999,29 @@ class TestSnippetCreateView(WagtailTestUtils, TestCase):
|
|
|
999
999
|
|
|
1000
1000
|
def test_create_invalid(self):
|
|
1001
1001
|
response = self.post(post_data={"foo": "bar"})
|
|
1002
|
-
self.assertContains(response, "The advert could not be created due to errors.")
|
|
1003
|
-
self.assertContains(response, "error-message", count=1)
|
|
1004
|
-
self.assertContains(response, "This field is required", count=1)
|
|
1005
1002
|
|
|
1006
1003
|
soup = self.get_soup(response.content)
|
|
1007
1004
|
|
|
1005
|
+
header_messages = soup.css.select(".messages[role='status'] ul > li")
|
|
1006
|
+
|
|
1007
|
+
# there should be one header message that indicates the issue and has a go to error button
|
|
1008
|
+
self.assertEqual(len(header_messages), 1)
|
|
1009
|
+
message = header_messages[0]
|
|
1010
|
+
self.assertIn(
|
|
1011
|
+
"The advert could not be created due to errors.", message.get_text()
|
|
1012
|
+
)
|
|
1013
|
+
buttons = message.find_all("button")
|
|
1014
|
+
self.assertEqual(len(buttons), 1)
|
|
1015
|
+
self.assertEqual(buttons[0].attrs["data-controller"], "w-count w-focus")
|
|
1016
|
+
self.assertIn("Go to the first error", buttons[0].get_text())
|
|
1017
|
+
|
|
1018
|
+
# field specific error should be shown
|
|
1019
|
+
error_messages = soup.css.select(".error-message")
|
|
1020
|
+
self.assertEqual(len(error_messages), 1)
|
|
1021
|
+
error_message = error_messages[0]
|
|
1022
|
+
self.assertEqual(error_message.parent["id"], "panel-child-text-errors")
|
|
1023
|
+
self.assertIn("This field is required", error_message.get_text())
|
|
1024
|
+
|
|
1008
1025
|
# Should have the unsaved controller set up
|
|
1009
1026
|
editor_form = soup.select_one("#w-editor-form")
|
|
1010
1027
|
self.assertIsNotNone(editor_form)
|
|
@@ -1773,7 +1790,7 @@ class TestCreateDraftStateSnippet(WagtailTestUtils, TestCase):
|
|
|
1773
1790
|
self.assertFormError(
|
|
1774
1791
|
response.context["form"],
|
|
1775
1792
|
"expire_at",
|
|
1776
|
-
"Expiry date/time must be in the future",
|
|
1793
|
+
"Expiry date/time must be in the future.",
|
|
1777
1794
|
)
|
|
1778
1795
|
|
|
1779
1796
|
self.assertContains(
|
|
@@ -1992,12 +2009,30 @@ class TestSnippetEditView(BaseTestSnippetEditView):
|
|
|
1992
2009
|
|
|
1993
2010
|
def test_edit_invalid(self):
|
|
1994
2011
|
response = self.post(post_data={"foo": "bar"})
|
|
1995
|
-
self.assertContains(response, "The advert could not be saved due to errors.")
|
|
1996
|
-
self.assertContains(response, "error-message", count=1)
|
|
1997
|
-
self.assertContains(response, "This field is required", count=1)
|
|
1998
|
-
|
|
1999
2012
|
soup = self.get_soup(response.content)
|
|
2000
2013
|
|
|
2014
|
+
header_messages = soup.css.select(".messages[role='status'] ul > li")
|
|
2015
|
+
|
|
2016
|
+
# the top level message should indicate that the page could not be saved
|
|
2017
|
+
self.assertEqual(len(header_messages), 1)
|
|
2018
|
+
message = header_messages[0]
|
|
2019
|
+
self.assertIn(
|
|
2020
|
+
"The advert could not be saved due to errors.", message.get_text()
|
|
2021
|
+
)
|
|
2022
|
+
|
|
2023
|
+
# the top level message should provide a go to error button
|
|
2024
|
+
buttons = message.find_all("button")
|
|
2025
|
+
self.assertEqual(len(buttons), 1)
|
|
2026
|
+
self.assertEqual(buttons[0].attrs["data-controller"], "w-count w-focus")
|
|
2027
|
+
self.assertIn("Go to the first error", buttons[0].get_text())
|
|
2028
|
+
|
|
2029
|
+
# the error should only appear once: against the field, not in the header message
|
|
2030
|
+
error_messages = soup.css.select(".error-message")
|
|
2031
|
+
self.assertEqual(len(error_messages), 1)
|
|
2032
|
+
error_message = error_messages[0]
|
|
2033
|
+
self.assertEqual(error_message.parent["id"], "panel-child-text-errors")
|
|
2034
|
+
self.assertIn("This field is required", error_message.get_text())
|
|
2035
|
+
|
|
2001
2036
|
# Should have the unsaved controller set up
|
|
2002
2037
|
editor_form = soup.select_one("#w-editor-form")
|
|
2003
2038
|
self.assertIsNotNone(editor_form)
|
|
@@ -3086,7 +3121,7 @@ class TestEditDraftStateSnippet(BaseTestSnippetEditView):
|
|
|
3086
3121
|
self.assertFormError(
|
|
3087
3122
|
response.context["form"],
|
|
3088
3123
|
"expire_at",
|
|
3089
|
-
"Expiry date/time must be in the future",
|
|
3124
|
+
"Expiry date/time must be in the future.",
|
|
3090
3125
|
)
|
|
3091
3126
|
|
|
3092
3127
|
self.assertContains(
|
|
@@ -5972,11 +6007,29 @@ class TestSnippetViewWithCustomPrimaryKey(WagtailTestUtils, TestCase):
|
|
|
5972
6007
|
|
|
5973
6008
|
def test_edit_invalid(self):
|
|
5974
6009
|
response = self.post(self.snippet_a, post_data={"foo": "bar"})
|
|
5975
|
-
self.
|
|
5976
|
-
|
|
6010
|
+
soup = self.get_soup(response.content)
|
|
6011
|
+
header_messages = soup.css.select(".messages[role='status'] ul > li")
|
|
6012
|
+
|
|
6013
|
+
# the top level message should indicate that the page could not be saved
|
|
6014
|
+
self.assertEqual(len(header_messages), 1)
|
|
6015
|
+
message = header_messages[0]
|
|
6016
|
+
self.assertIn(
|
|
5977
6017
|
"The standard snippet with custom primary key could not be saved due to errors.",
|
|
6018
|
+
message.get_text(),
|
|
5978
6019
|
)
|
|
5979
|
-
|
|
6020
|
+
|
|
6021
|
+
# the top level message should provide a go to error button
|
|
6022
|
+
buttons = message.find_all("button")
|
|
6023
|
+
self.assertEqual(len(buttons), 1)
|
|
6024
|
+
self.assertEqual(buttons[0].attrs["data-controller"], "w-count w-focus")
|
|
6025
|
+
self.assertIn("Go to the first error", buttons[0].get_text())
|
|
6026
|
+
|
|
6027
|
+
# the errors should appear against the fields with issues
|
|
6028
|
+
error_messages = soup.css.select(".error-message")
|
|
6029
|
+
self.assertEqual(len(error_messages), 2)
|
|
6030
|
+
error_message = error_messages[0]
|
|
6031
|
+
self.assertEqual(error_message.parent["id"], "panel-child-snippet_id-errors")
|
|
6032
|
+
self.assertIn("This field is required", error_message.get_text())
|
|
5980
6033
|
|
|
5981
6034
|
def test_edit(self):
|
|
5982
6035
|
response = self.post(
|
|
@@ -444,6 +444,14 @@ class WorkflowHistoryDetailView(
|
|
|
444
444
|
permission_required = "change"
|
|
445
445
|
|
|
446
446
|
|
|
447
|
+
class ReorderView(generic.ReorderView):
|
|
448
|
+
@cached_property
|
|
449
|
+
def permission_required(self):
|
|
450
|
+
if issubclass(self.model, DraftStateMixin):
|
|
451
|
+
return "publish"
|
|
452
|
+
return super().permission_required
|
|
453
|
+
|
|
454
|
+
|
|
447
455
|
class SnippetViewSet(ModelViewSet):
|
|
448
456
|
"""
|
|
449
457
|
A viewset that instantiates the admin views for snippets.
|
|
@@ -505,6 +513,9 @@ class SnippetViewSet(ModelViewSet):
|
|
|
505
513
|
#: The view class to use for the inspect view; must be a subclass of ``wagtail.snippets.views.snippets.InspectView``.
|
|
506
514
|
inspect_view_class = InspectView
|
|
507
515
|
|
|
516
|
+
#: The view class to use for the reorder view; must be a subclass of ``wagtail.snippets.views.snippets.ReorderView``.
|
|
517
|
+
reorder_view_class = ReorderView
|
|
518
|
+
|
|
508
519
|
#: The view class to use for previewing revisions; must be a subclass of ``wagtail.snippets.views.snippets.PreviewRevisionView``.
|
|
509
520
|
revisions_view_class = PreviewRevisionView
|
|
510
521
|
|
|
@@ -1048,6 +1059,11 @@ class SnippetViewSet(ModelViewSet):
|
|
|
1048
1059
|
),
|
|
1049
1060
|
]
|
|
1050
1061
|
|
|
1062
|
+
if self.reorder_view_enabled:
|
|
1063
|
+
urlpatterns += [
|
|
1064
|
+
path("reorder/<str:pk>/", self.reorder_view, name="reorder")
|
|
1065
|
+
]
|
|
1066
|
+
|
|
1051
1067
|
if self.copy_view_enabled:
|
|
1052
1068
|
urlpatterns += [path("copy/<str:pk>/", self.copy_view, name="copy")]
|
|
1053
1069
|
|
wagtail/test/numberformat.py
CHANGED
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
# USE_THOUSAND_SEPARATOR = True incorrectly reformats numbers that are not intended to be
|
|
5
5
|
# human-readable (such as image dimensions, or IDs within data attributes).
|
|
6
6
|
|
|
7
|
+
from contextlib import contextmanager
|
|
7
8
|
from decimal import Decimal
|
|
8
9
|
|
|
9
10
|
import django.contrib.humanize.templatetags.humanize
|
|
11
|
+
import django.template.base
|
|
10
12
|
import django.template.defaultfilters
|
|
11
13
|
import django.templatetags.l10n
|
|
12
14
|
import django.utils.numberformat
|
|
@@ -17,6 +19,34 @@ from django.utils.translation import gettext, ngettext
|
|
|
17
19
|
|
|
18
20
|
original_numberformat = django.utils.numberformat.format
|
|
19
21
|
original_intcomma = django.contrib.humanize.templatetags.humanize.intcomma
|
|
22
|
+
OriginalVariableNode = django.template.base.VariableNode
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@contextmanager
|
|
26
|
+
def ignore_numberformat(template_names):
|
|
27
|
+
class VariableNode(OriginalVariableNode):
|
|
28
|
+
def render(self, context):
|
|
29
|
+
template_name = context.render_context.template.origin.template_name
|
|
30
|
+
# If the template being rendered is in the list of templates to ignore,
|
|
31
|
+
# restore the original numberformat function so the template can render
|
|
32
|
+
# normally, otherwise reinforce the patch as there might be multiple
|
|
33
|
+
# templates being rendered in the lifespan of the contextmanager.
|
|
34
|
+
if template_name in template_names:
|
|
35
|
+
django.utils.numberformat.format = original_numberformat
|
|
36
|
+
else:
|
|
37
|
+
django.utils.numberformat.format = patched_numberformat
|
|
38
|
+
|
|
39
|
+
return super().render(context)
|
|
40
|
+
|
|
41
|
+
# Within the contextmanager, use a VariableNode class that conditionally
|
|
42
|
+
# enforces the numberformat patch
|
|
43
|
+
django.template.base.VariableNode = VariableNode
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
yield
|
|
47
|
+
finally:
|
|
48
|
+
# Restore VariableNode to always enforce the numberformat patch
|
|
49
|
+
django.template.base.VariableNode = OriginalVariableNode
|
|
20
50
|
|
|
21
51
|
|
|
22
52
|
def patched_numberformat(*args, use_l10n=None, **kwargs):
|
wagtail/test/settings.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
|
|
3
3
|
from django.contrib.messages import constants as message_constants
|
|
4
|
+
from django.core.exceptions import ImproperlyConfigured
|
|
4
5
|
from django.utils.translation import gettext_lazy as _
|
|
5
6
|
|
|
6
7
|
from wagtail.test.numberformat import patch_number_formats
|
|
@@ -151,7 +152,6 @@ INSTALLED_APPS = [
|
|
|
151
152
|
"wagtail.test.demosite",
|
|
152
153
|
"wagtail.test.snippets",
|
|
153
154
|
"wagtail.test.routablepage",
|
|
154
|
-
"wagtail.test.search",
|
|
155
155
|
"wagtail.test.i18n",
|
|
156
156
|
"wagtail.test.streamfield_migrations",
|
|
157
157
|
"wagtail.contrib.simple_translation",
|
|
@@ -229,25 +229,48 @@ else:
|
|
|
229
229
|
|
|
230
230
|
if os.environ.get("DATABASE_ENGINE") == "django.db.backends.postgresql":
|
|
231
231
|
INSTALLED_APPS.append("django.contrib.postgres")
|
|
232
|
-
WAGTAILSEARCH_BACKENDS["postgresql"] = {
|
|
233
|
-
"BACKEND": "wagtail.search.backends.database",
|
|
234
|
-
"AUTO_UPDATE": False,
|
|
235
|
-
"SEARCH_CONFIG": "english",
|
|
236
|
-
}
|
|
237
232
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
233
|
+
# Tests in wagtail.tests.test_page_search.PageSearchTests will be run against each backend defined
|
|
234
|
+
# in WAGTAILSEARCH_BACKENDS. Define an additional one to test the FTS-enabled backend for the
|
|
235
|
+
# currently active database.
|
|
236
|
+
|
|
237
|
+
WAGTAILSEARCH_BACKENDS["database"] = {
|
|
238
|
+
"BACKEND": "wagtail.search.backends.database",
|
|
239
|
+
"AUTO_UPDATE": False,
|
|
240
|
+
"SEARCH_CONFIG": "english",
|
|
241
|
+
}
|
|
243
242
|
|
|
244
|
-
|
|
243
|
+
if "ELASTICSEARCH_URL" in os.environ:
|
|
244
|
+
# Define an 'elasticsearch' backend; along with wagtail.tests.test_page_search.PageSearchTests
|
|
245
|
+
# this is also used for the Elasticsearch-specific tests in wagtail.images.tests.test_models and
|
|
246
|
+
# wagtail.documents.tests.test_search. We also want to run these tests under Opensearch; for
|
|
247
|
+
# simplicity we use the backend name 'elasticsearch' in this case too.
|
|
248
|
+
if elasticsearch_version := os.environ.get("ELASTICSEARCH_VERSION"):
|
|
249
|
+
backend = f"wagtail.search.backends.elasticsearch{elasticsearch_version}"
|
|
250
|
+
elif opensearch_version := os.environ.get("OPENSEARCH_VERSION"):
|
|
251
|
+
backend = f"wagtail.search.backends.opensearch{opensearch_version}"
|
|
252
|
+
else:
|
|
253
|
+
raise ImproperlyConfigured(
|
|
254
|
+
"If ELASTICSEARCH_URL is defined, either ELASTICSEARCH_VERSION or OPENSEARCH_VERSION must be defined too"
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
elasticsearch_opts = {
|
|
245
258
|
"BACKEND": backend,
|
|
246
259
|
"URLS": [os.environ["ELASTICSEARCH_URL"]],
|
|
247
260
|
"TIMEOUT": 10,
|
|
248
261
|
"max_retries": 1,
|
|
249
262
|
"AUTO_UPDATE": False,
|
|
250
263
|
"INDEX_SETTINGS": {"settings": {"index": {"number_of_shards": 1}}},
|
|
264
|
+
"OPTIONS": {
|
|
265
|
+
"ca_certs": os.environ.get("ELASTICSEARCH_CA_CERTS"),
|
|
266
|
+
},
|
|
267
|
+
}
|
|
268
|
+
WAGTAILSEARCH_BACKENDS["elasticsearch"] = elasticsearch_opts
|
|
269
|
+
|
|
270
|
+
# RemovedInWagtail80Warning
|
|
271
|
+
WAGTAILSEARCH_BACKENDS["elasticsearch_with_index_option"] = {
|
|
272
|
+
**elasticsearch_opts,
|
|
273
|
+
"INDEX": "wagtailtest", # Deprecated option
|
|
251
274
|
}
|
|
252
275
|
|
|
253
276
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from wagtail.coreutils import multigetattr
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CommentableJSONField(models.JSONField):
|
|
7
|
+
def get_block_by_content_path(self, value, path_elements):
|
|
8
|
+
try:
|
|
9
|
+
multigetattr(value, ".".join(path_elements))
|
|
10
|
+
except AttributeError:
|
|
11
|
+
return False
|
|
12
|
+
return True
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Generated by Django 5.2.5 on 2025-08-14 19:05
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
import wagtail.fields
|
|
7
|
+
import wagtail.test.testapp.fields
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Migration(migrations.Migration):
|
|
11
|
+
|
|
12
|
+
dependencies = [
|
|
13
|
+
("tests", "0055_previewable_settings"),
|
|
14
|
+
("wagtailcore", "0095_groupsitepermission"),
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
operations = [
|
|
18
|
+
migrations.CreateModel(
|
|
19
|
+
name="CommentableJSONPage",
|
|
20
|
+
fields=[
|
|
21
|
+
(
|
|
22
|
+
"page_ptr",
|
|
23
|
+
models.OneToOneField(
|
|
24
|
+
auto_created=True,
|
|
25
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
26
|
+
parent_link=True,
|
|
27
|
+
primary_key=True,
|
|
28
|
+
serialize=False,
|
|
29
|
+
to="wagtailcore.page",
|
|
30
|
+
),
|
|
31
|
+
),
|
|
32
|
+
(
|
|
33
|
+
"commentable_body",
|
|
34
|
+
wagtail.test.testapp.fields.CommentableJSONField(),
|
|
35
|
+
),
|
|
36
|
+
("uncommentable_body", models.JSONField()),
|
|
37
|
+
(
|
|
38
|
+
"stream_body",
|
|
39
|
+
wagtail.fields.StreamField(
|
|
40
|
+
[("text", 0)],
|
|
41
|
+
block_lookup={0: ("wagtail.blocks.CharBlock", (), {})},
|
|
42
|
+
),
|
|
43
|
+
),
|
|
44
|
+
],
|
|
45
|
+
options={
|
|
46
|
+
"abstract": False,
|
|
47
|
+
},
|
|
48
|
+
bases=("wagtailcore.page",),
|
|
49
|
+
),
|
|
50
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Generated by Django 5.1.6 on 2025-03-08 13:10
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("tests", "0056_commentablejsonpage"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="featurecompletetoy",
|
|
15
|
+
name="sort_order",
|
|
16
|
+
field=models.IntegerField(blank=True, null=True),
|
|
17
|
+
),
|
|
18
|
+
migrations.AddField(
|
|
19
|
+
model_name="fullfeaturedsnippet",
|
|
20
|
+
name="sort_order",
|
|
21
|
+
field=models.IntegerField(blank=True, editable=False, null=True),
|
|
22
|
+
),
|
|
23
|
+
]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Generated by Django 5.1.6 on 2025-07-14 16:16
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("tests", "0057_featurecompletetoy_sort_order"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.CreateModel(
|
|
15
|
+
name="CustomLockTask",
|
|
16
|
+
fields=[
|
|
17
|
+
(
|
|
18
|
+
"task_ptr",
|
|
19
|
+
models.OneToOneField(
|
|
20
|
+
auto_created=True,
|
|
21
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
22
|
+
parent_link=True,
|
|
23
|
+
primary_key=True,
|
|
24
|
+
serialize=False,
|
|
25
|
+
to="wagtailcore.task",
|
|
26
|
+
),
|
|
27
|
+
),
|
|
28
|
+
],
|
|
29
|
+
bases=("wagtailcore.task",),
|
|
30
|
+
),
|
|
31
|
+
]
|
wagtail/test/testapp/models.py
CHANGED
|
@@ -88,6 +88,8 @@ from wagtail.search import index
|
|
|
88
88
|
from wagtail.snippets.blocks import SnippetChooserBlock
|
|
89
89
|
from wagtail.snippets.models import register_snippet
|
|
90
90
|
|
|
91
|
+
from ...locks import WorkflowLock
|
|
92
|
+
from .fields import CommentableJSONField
|
|
91
93
|
from .forms import FormClassAdditionalFieldPageForm, ValidatedPageForm
|
|
92
94
|
|
|
93
95
|
EVENT_AUDIENCE_CHOICES = (
|
|
@@ -1301,6 +1303,7 @@ class FullFeaturedSnippet(
|
|
|
1301
1303
|
LockableMixin,
|
|
1302
1304
|
RevisionMixin,
|
|
1303
1305
|
TranslatableMixin,
|
|
1306
|
+
Orderable,
|
|
1304
1307
|
index.Indexed,
|
|
1305
1308
|
models.Model,
|
|
1306
1309
|
):
|
|
@@ -2448,6 +2451,18 @@ class UserApprovalTask(Task):
|
|
|
2448
2451
|
return "Only a specific user can approve this task"
|
|
2449
2452
|
|
|
2450
2453
|
|
|
2454
|
+
class CustomWorkflowLock(WorkflowLock):
|
|
2455
|
+
def get_message(self, user):
|
|
2456
|
+
return "If there is a door, there must be a key"
|
|
2457
|
+
|
|
2458
|
+
|
|
2459
|
+
class CustomLockTask(Task):
|
|
2460
|
+
lock_class = CustomWorkflowLock
|
|
2461
|
+
|
|
2462
|
+
def locked_for_user(self, obj, user):
|
|
2463
|
+
return True
|
|
2464
|
+
|
|
2465
|
+
|
|
2451
2466
|
# StreamField media definitions must not be evaluated at startup (e.g. during system checks) -
|
|
2452
2467
|
# these may fail if e.g. ManifestStaticFilesStorage is in use and collectstatic has not been run.
|
|
2453
2468
|
# Check this with a media definition that deliberately errors; if media handling is not set up
|
|
@@ -2587,6 +2602,8 @@ class FeatureCompleteToy(index.Indexed, models.Model):
|
|
|
2587
2602
|
)
|
|
2588
2603
|
name = models.CharField(max_length=255)
|
|
2589
2604
|
release_date = models.DateField(default=datetime.date.today)
|
|
2605
|
+
sort_order = models.IntegerField(null=True, blank=True)
|
|
2606
|
+
sort_order_field = "sort_order"
|
|
2590
2607
|
|
|
2591
2608
|
search_fields = [
|
|
2592
2609
|
index.SearchField("name"),
|
|
@@ -2676,3 +2693,13 @@ class RequiredDatePage(Page):
|
|
|
2676
2693
|
TitleFieldPanel("title", classname="title"),
|
|
2677
2694
|
FieldPanel("deadline"),
|
|
2678
2695
|
]
|
|
2696
|
+
|
|
2697
|
+
|
|
2698
|
+
class CommentableJSONPage(Page):
|
|
2699
|
+
commentable_body = CommentableJSONField()
|
|
2700
|
+
uncommentable_body = models.JSONField()
|
|
2701
|
+
stream_body = StreamField(
|
|
2702
|
+
[
|
|
2703
|
+
("text", CharBlock()),
|
|
2704
|
+
]
|
|
2705
|
+
)
|
wagtail/test/testapp/views.py
CHANGED
|
@@ -246,6 +246,7 @@ class FeatureCompleteToyViewSet(ModelViewSet):
|
|
|
246
246
|
# search_fields derived from the model
|
|
247
247
|
inspect_view_enabled = True
|
|
248
248
|
inspect_view_fields = ["strid", "release_date"]
|
|
249
|
+
sort_order_field = "sort_order"
|
|
249
250
|
|
|
250
251
|
panels = [
|
|
251
252
|
FieldPanel("name"),
|
|
@@ -266,7 +267,7 @@ class FCToyAlt1ViewSet(ModelViewSet):
|
|
|
266
267
|
menu_label = "FC Toys Alt 1"
|
|
267
268
|
inspect_view_class = FCToyAlt1InspectView
|
|
268
269
|
inspect_view_enabled = True
|
|
269
|
-
inspect_view_fields_exclude = ["strid", "release_date"]
|
|
270
|
+
inspect_view_fields_exclude = ["strid", "release_date", "sort_order"]
|
|
270
271
|
copy_view_enabled = False
|
|
271
272
|
|
|
272
273
|
def get_index_view_kwargs(self, **kwargs):
|
|
@@ -295,6 +296,7 @@ class ToyViewSetGroup(ModelViewSetGroup):
|
|
|
295
296
|
exclude_form_fields=(),
|
|
296
297
|
search_fields=["name"],
|
|
297
298
|
search_backend_name=None,
|
|
299
|
+
sort_order_field=None,
|
|
298
300
|
),
|
|
299
301
|
ModelViewSet(
|
|
300
302
|
name="fctoy-alt3",
|
wagtail/test/utils/page_tests.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any
|
|
2
2
|
from unittest import mock
|
|
3
3
|
|
|
4
4
|
from django.conf import settings
|
|
@@ -174,8 +174,8 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
174
174
|
def assertPageIsRoutable(
|
|
175
175
|
self,
|
|
176
176
|
page: Page,
|
|
177
|
-
route_path:
|
|
178
|
-
msg:
|
|
177
|
+
route_path: str | None = "/",
|
|
178
|
+
msg: str | None = None,
|
|
179
179
|
):
|
|
180
180
|
"""
|
|
181
181
|
Asserts that ``page`` can be routed to without raising a ``Http404`` error.
|
|
@@ -216,13 +216,13 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
216
216
|
def assertPageIsRenderable(
|
|
217
217
|
self,
|
|
218
218
|
page: Page,
|
|
219
|
-
route_path:
|
|
220
|
-
query_data:
|
|
221
|
-
post_data:
|
|
222
|
-
user:
|
|
223
|
-
accept_404:
|
|
224
|
-
accept_redirect:
|
|
225
|
-
msg:
|
|
219
|
+
route_path: str | None = "/",
|
|
220
|
+
query_data: dict[str, Any] | None = None,
|
|
221
|
+
post_data: dict[str, Any] | None = None,
|
|
222
|
+
user: AbstractBaseUser | None = None,
|
|
223
|
+
accept_404: bool | None = False,
|
|
224
|
+
accept_redirect: bool | None = False,
|
|
225
|
+
msg: str | None = None,
|
|
226
226
|
):
|
|
227
227
|
"""
|
|
228
228
|
Asserts that ``page`` can be rendered without raising a fatal error.
|
|
@@ -297,9 +297,9 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
297
297
|
def assertPageIsEditable(
|
|
298
298
|
self,
|
|
299
299
|
page: Page,
|
|
300
|
-
post_data:
|
|
301
|
-
user:
|
|
302
|
-
msg:
|
|
300
|
+
post_data: dict[str, Any] | None = None,
|
|
301
|
+
user: AbstractBaseUser | None = None,
|
|
302
|
+
msg: str | None = None,
|
|
303
303
|
):
|
|
304
304
|
"""
|
|
305
305
|
Asserts that the page edit view works for ``page`` without raising a fatal error.
|
|
@@ -378,10 +378,10 @@ class WagtailPageTestCase(WagtailTestUtils, TestCase):
|
|
|
378
378
|
def assertPageIsPreviewable(
|
|
379
379
|
self,
|
|
380
380
|
page: Page,
|
|
381
|
-
mode:
|
|
382
|
-
post_data:
|
|
383
|
-
user:
|
|
384
|
-
msg:
|
|
381
|
+
mode: str | None = "",
|
|
382
|
+
post_data: dict[str, Any] | None = None,
|
|
383
|
+
user: AbstractBaseUser | None = None,
|
|
384
|
+
msg: str | None = None,
|
|
385
385
|
):
|
|
386
386
|
"""
|
|
387
387
|
Asserts that the page preview view can be loaded for ``page`` without raising a fatal error.
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Union
|
|
2
|
-
|
|
3
1
|
from django.test import SimpleTestCase
|
|
4
2
|
|
|
5
3
|
from .wagtail_tests import WagtailTestUtils
|
|
@@ -9,9 +7,9 @@ class AdminTemplateTestUtils:
|
|
|
9
7
|
base_breadcrumb_items = [{"label": "Home", "url": "/admin/"}]
|
|
10
8
|
|
|
11
9
|
def assertBreadcrumbsItemsRendered(
|
|
12
|
-
self:
|
|
10
|
+
self: WagtailTestUtils | SimpleTestCase,
|
|
13
11
|
items: list[dict[str, str]],
|
|
14
|
-
html:
|
|
12
|
+
html: str | bytes,
|
|
15
13
|
):
|
|
16
14
|
soup = self.get_soup(html)
|
|
17
15
|
# Select with a class instead of a data-controller attribute because
|
|
@@ -79,8 +77,8 @@ class AdminTemplateTestUtils:
|
|
|
79
77
|
)
|
|
80
78
|
|
|
81
79
|
def assertBreadcrumbsNotRendered(
|
|
82
|
-
self:
|
|
83
|
-
html:
|
|
80
|
+
self: WagtailTestUtils | SimpleTestCase,
|
|
81
|
+
html: str | bytes,
|
|
84
82
|
):
|
|
85
83
|
soup = self.get_soup(html)
|
|
86
84
|
# Select with a class instead of a data-controller attribute because
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import warnings
|
|
2
2
|
from contextlib import contextmanager
|
|
3
|
-
from typing import Union
|
|
4
3
|
|
|
5
4
|
from bs4 import BeautifulSoup
|
|
6
5
|
from django.contrib.auth import get_user_model
|
|
@@ -9,7 +8,7 @@ from django.test.testcases import assert_and_parse_html
|
|
|
9
8
|
|
|
10
9
|
class WagtailTestUtils:
|
|
11
10
|
@staticmethod
|
|
12
|
-
def get_soup(markup:
|
|
11
|
+
def get_soup(markup: str | bytes) -> BeautifulSoup:
|
|
13
12
|
# Use an empty string_containers argument so that <script>, <style>, and
|
|
14
13
|
# <template> tags do not have their text ignored.
|
|
15
14
|
return BeautifulSoup(markup, "html.parser", string_containers={})
|
wagtail/tests/test_page_model.py
CHANGED
|
@@ -3,6 +3,7 @@ import json
|
|
|
3
3
|
import unittest
|
|
4
4
|
from unittest.mock import Mock
|
|
5
5
|
|
|
6
|
+
from asgiref.sync import async_to_sync
|
|
6
7
|
from django.conf import settings
|
|
7
8
|
from django.contrib.auth import get_user_model
|
|
8
9
|
from django.contrib.auth.models import AnonymousUser, Group
|
|
@@ -196,6 +197,20 @@ class TestValidation(TestCase):
|
|
|
196
197
|
self.assertEqual(retrieved_page.draft_title, "Hello world edited")
|
|
197
198
|
|
|
198
199
|
|
|
200
|
+
class TestAsyncMethods(TestCase):
|
|
201
|
+
def test_asave_with_update_fields_none_saves_all_fields(self):
|
|
202
|
+
root = Page.get_first_root_node()
|
|
203
|
+
page = Page(title="Original title", slug="async-page")
|
|
204
|
+
root.add_child(instance=page)
|
|
205
|
+
|
|
206
|
+
# Call asave using async_to_sync
|
|
207
|
+
page.title = "Updated title"
|
|
208
|
+
async_to_sync(page.asave)()
|
|
209
|
+
|
|
210
|
+
refreshed = Page.objects.get(id=page.id)
|
|
211
|
+
assert refreshed.title == "Updated title"
|
|
212
|
+
|
|
213
|
+
|
|
199
214
|
@override_settings(
|
|
200
215
|
ALLOWED_HOSTS=[
|
|
201
216
|
"localhost",
|
|
@@ -1,14 +1,41 @@
|
|
|
1
|
+
from unittest import mock
|
|
2
|
+
|
|
1
3
|
from django.conf import settings
|
|
2
4
|
from django.db.models import F
|
|
3
|
-
from django.test import TestCase
|
|
5
|
+
from django.test import TestCase, override_settings
|
|
4
6
|
|
|
5
7
|
from wagtail.models import Page
|
|
8
|
+
from wagtail.search import index
|
|
6
9
|
from wagtail.search.backends import get_search_backend
|
|
7
10
|
from wagtail.search.backends.base import (
|
|
8
11
|
BaseSearchQueryCompiler,
|
|
9
12
|
BaseSearchResults,
|
|
10
13
|
OrderByFieldError,
|
|
11
14
|
)
|
|
15
|
+
from wagtail.test.testapp.models import SimplePage
|
|
16
|
+
from wagtail.test.utils import WagtailTestUtils
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@mock.patch("wagtail.tests.DummySearchBackend", create=True)
|
|
20
|
+
@override_settings(
|
|
21
|
+
WAGTAILSEARCH_BACKENDS={"default": {"BACKEND": "wagtail.tests.DummySearchBackend"}}
|
|
22
|
+
)
|
|
23
|
+
class TestInsertOrUpdateObject(WagtailTestUtils, TestCase):
|
|
24
|
+
def test_converts_to_specific_page(self, backend):
|
|
25
|
+
root_page = Page.objects.get(id=1)
|
|
26
|
+
page = root_page.add_child(
|
|
27
|
+
instance=SimplePage(title="test", slug="test", content="test")
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Convert page into a generic "Page" object and add it into the index
|
|
31
|
+
unspecific_page = page.page_ptr
|
|
32
|
+
|
|
33
|
+
backend().reset_mock()
|
|
34
|
+
|
|
35
|
+
index.insert_or_update_object(unspecific_page)
|
|
36
|
+
|
|
37
|
+
# It should be automatically converted back to the specific version
|
|
38
|
+
backend().add.assert_called_with(page)
|
|
12
39
|
|
|
13
40
|
|
|
14
41
|
class PageSearchTests:
|
|
@@ -55,7 +82,7 @@ class PageSearchTests:
|
|
|
55
82
|
"blah", order_by_relevance=False, backend=self.backend_name
|
|
56
83
|
)
|
|
57
84
|
self.assertIn(
|
|
58
|
-
'
|
|
85
|
+
'Sorting search results with "OrderBy(F(last_published_at), descending=False)" is not supported by this search backend.',
|
|
59
86
|
str(ctx.exception),
|
|
60
87
|
)
|
|
61
88
|
|