wagtail 6.3.2__py3-none-any.whl → 6.4rc1__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/publish_revision.py +4 -5
- wagtail/admin/auth.py +0 -2
- wagtail/admin/checks.py +1 -1
- wagtail/admin/filters.py +3 -1
- wagtail/admin/forms/account.py +21 -11
- wagtail/admin/forms/collections.py +2 -9
- wagtail/admin/forms/formsets.py +32 -0
- wagtail/admin/forms/pages.py +5 -1
- wagtail/admin/forms/workflows.py +2 -13
- wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/django.po +68 -1
- wagtail/admin/locale/ar/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/djangojs.po +5 -1
- wagtail/admin/locale/en/LC_MESSAGES/django.po +312 -356
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -16
- wagtail/admin/menu.py +0 -13
- wagtail/admin/panels/base.py +2 -2
- wagtail/admin/panels/group.py +4 -1
- wagtail/admin/panels/inline_panel.py +5 -2
- wagtail/admin/panels/model_utils.py +36 -0
- wagtail/admin/panels/page_utils.py +2 -40
- wagtail/admin/panels/signal_handlers.py +0 -2
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/streamfield.css +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 -8
- wagtail/admin/static/wagtailadmin/js/draftail.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/privacy-switch.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +7 -0
- wagtail/admin/templates/wagtailadmin/404.html +4 -0
- wagtail/admin/templates/wagtailadmin/chooser/browse.html +2 -1
- wagtail/admin/templates/wagtailadmin/chooser/tables/parent_page_cell.html +1 -1
- wagtail/admin/templates/wagtailadmin/collections/_privacy_switch.html +8 -1
- wagtail/admin/templates/wagtailadmin/generic/confirm_delete.html +15 -9
- wagtail/admin/templates/wagtailadmin/generic/confirm_unpublish.html +21 -25
- wagtail/admin/templates/wagtailadmin/generic/form.html +1 -1
- wagtail/admin/templates/wagtailadmin/generic/preview_error.html +3 -0
- wagtail/admin/templates/wagtailadmin/generic/revisions/compare.html +63 -76
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -2
- wagtail/admin/templates/wagtailadmin/pages/edit.html +1 -5
- wagtail/admin/templates/wagtailadmin/panels/inline_panel_child.html +1 -0
- wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_form.html +1 -1
- wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html +6 -22
- wagtail/admin/templates/wagtailadmin/shared/formatted_field.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/header.html +2 -2
- wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +32 -39
- wagtail/admin/templates/wagtailadmin/shared/revisions/confirm_unschedule.html +13 -17
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/privacy.html +15 -3
- wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +1 -1
- wagtail/admin/templates/wagtailadmin/skeleton.html +4 -2
- wagtail/admin/templates/wagtailadmin/workflows/create.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/edit.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_pages_form.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_pages_formset.html +6 -23
- wagtail/admin/templatetags/wagtailadmin_tags.py +12 -0
- wagtail/admin/templatetags/wagtailuserbar.py +2 -3
- wagtail/admin/tests/pages/test_create_page.py +110 -1
- wagtail/admin/tests/pages/test_edit_page.py +3 -2
- wagtail/admin/tests/pages/test_explorer_view.py +18 -0
- wagtail/admin/tests/pages/test_page_usage.py +24 -20
- wagtail/admin/tests/pages/test_preview.py +69 -1
- wagtail/admin/tests/pages/test_revisions.py +40 -6
- wagtail/admin/tests/test_account_management.py +39 -1
- wagtail/admin/tests/test_audit_log.py +4 -2
- wagtail/admin/tests/test_block_preview.py +224 -0
- wagtail/admin/tests/test_edit_handlers.py +23 -6
- wagtail/admin/tests/test_page_chooser.py +50 -3
- wagtail/admin/tests/test_privacy.py +49 -26
- wagtail/admin/tests/test_site_summary.py +15 -10
- wagtail/admin/tests/test_templatetags.py +19 -0
- wagtail/admin/tests/test_userbar.py +82 -1
- wagtail/admin/tests/test_views_generic.py +27 -12
- wagtail/admin/tests/test_workflows.py +69 -0
- wagtail/admin/tests/tests.py +23 -4
- wagtail/admin/tests/ui/test_sidebar.py +1 -1
- wagtail/admin/tests/viewsets/test_model_viewset.py +15 -13
- wagtail/admin/ui/side_panels.py +7 -4
- wagtail/admin/urls/__init__.py +6 -0
- wagtail/admin/urls/pages.py +1 -1
- wagtail/admin/userbar.py +21 -1
- wagtail/admin/views/account.py +5 -0
- wagtail/admin/views/chooser.py +5 -1
- wagtail/admin/views/collections.py +0 -2
- wagtail/admin/views/generic/base.py +20 -10
- wagtail/admin/views/generic/history.py +0 -1
- wagtail/admin/views/generic/models.py +79 -21
- wagtail/admin/views/generic/preview.py +50 -1
- wagtail/admin/views/mixins.py +4 -2
- wagtail/admin/views/pages/bulk_actions/delete.py +11 -23
- wagtail/admin/views/pages/bulk_actions/page_bulk_action.py +17 -0
- wagtail/admin/views/pages/bulk_actions/publish.py +11 -31
- wagtail/admin/views/pages/bulk_actions/unpublish.py +11 -31
- wagtail/admin/views/pages/create.py +1 -0
- wagtail/admin/views/pages/edit.py +38 -30
- wagtail/admin/views/pages/revisions.py +43 -114
- wagtail/admin/views/pages/utils.py +0 -1
- wagtail/admin/views/tags.py +6 -2
- wagtail/admin/views/workflows.py +8 -6
- wagtail/admin/viewsets/model.py +0 -4
- wagtail/admin/viewsets/pages.py +0 -1
- wagtail/admin/widgets/tags.py +1 -0
- wagtail/api/v2/tests/test_documents.py +4 -2
- wagtail/api/v2/tests/test_images.py +4 -2
- wagtail/api/v2/tests/test_pages.py +8 -4
- wagtail/blocks/base.py +59 -1
- wagtail/blocks/field_block.py +6 -0
- wagtail/blocks/list_block.py +4 -0
- wagtail/blocks/static_block.py +3 -0
- wagtail/blocks/stream_block.py +5 -1
- wagtail/blocks/struct_block.py +6 -0
- wagtail/compat.py +16 -0
- wagtail/contrib/forms/forms.py +27 -7
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/forms/tests/test_models.py +7 -5
- wagtail/contrib/forms/tests/test_views.py +75 -0
- wagtail/contrib/frontend_cache/tasks.py +83 -0
- wagtail/contrib/frontend_cache/tests.py +47 -32
- wagtail/contrib/frontend_cache/utils.py +2 -70
- wagtail/contrib/redirects/base_formats.py +2 -2
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.po +3 -0
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +24 -37
- wagtail/contrib/redirects/templates/wagtailredirects/add.html +1 -24
- wagtail/contrib/redirects/templates/wagtailredirects/confirm_delete.html +3 -13
- wagtail/contrib/redirects/tests/test_redirects.py +122 -110
- wagtail/contrib/redirects/tests/test_signal_handlers.py +75 -69
- wagtail/contrib/redirects/urls.py +2 -2
- wagtail/contrib/redirects/views.py +35 -73
- wagtail/contrib/search_promotions/admin_urls.py +10 -3
- wagtail/contrib/search_promotions/forms.py +55 -26
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +44 -54
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/add.html +21 -31
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/confirm_delete.html +3 -12
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/edit.html +11 -34
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotion_form.html +1 -0
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/includes/searchpromotions_formset.js +2 -1
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +0 -1
- wagtail/contrib/search_promotions/tests.py +814 -13
- wagtail/contrib/search_promotions/views/__init__.py +1 -0
- wagtail/contrib/search_promotions/views/reports.py +56 -0
- wagtail/contrib/search_promotions/views/settings.py +258 -0
- wagtail/contrib/search_promotions/wagtail_hooks.py +12 -1
- wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/settings/templates/wagtailsettings/edit.html +1 -5
- wagtail/contrib/settings/tests/generic/test_admin.py +2 -5
- wagtail/contrib/settings/tests/generic/test_register.py +1 -1
- wagtail/contrib/settings/tests/site_specific/test_admin.py +2 -5
- wagtail/contrib/settings/tests/site_specific/test_register.py +1 -1
- wagtail/contrib/settings/views.py +9 -23
- 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/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/tests.py +4 -1
- wagtail/contrib/typed_table_block/blocks.py +3 -0
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/contrib/typed_table_block/tests.py +33 -0
- wagtail/documents/locale/en/LC_MESSAGES/django.po +26 -26
- wagtail/documents/migrations/0011_add_choose_permissions.py +1 -0
- wagtail/documents/models.py +1 -0
- wagtail/documents/signal_handlers.py +6 -2
- wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
- wagtail/documents/templates/wagtaildocs/documents/edit.html +1 -3
- wagtail/documents/templates/wagtaildocs/multiple/add.html +7 -1
- wagtail/documents/tests/test_admin_views.py +74 -33
- wagtail/documents/tests/test_views.py +21 -12
- wagtail/documents/views/chooser.py +1 -0
- wagtail/documents/views/documents.py +1 -2
- wagtail/documents/views/multiple.py +0 -1
- wagtail/documents/views/serve.py +9 -2
- wagtail/documents/wagtail_hooks.py +6 -1
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/oembed_providers.py +0 -64
- wagtail/fields.py +3 -0
- wagtail/images/apps.py +2 -1
- wagtail/images/blocks.py +6 -2
- wagtail/images/forms.py +40 -3
- wagtail/images/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ar/LC_MESSAGES/django.po +4 -0
- wagtail/images/locale/en/LC_MESSAGES/django.po +49 -49
- wagtail/images/migrations/0023_add_choose_permissions.py +1 -0
- wagtail/images/rich_text/contentstate.py +1 -0
- wagtail/images/rich_text/editor_html.py +1 -0
- wagtail/images/signal_handlers.py +17 -10
- wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
- wagtail/images/static/wagtailimages/js/image-block.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.fileupload-image.js +1 -1
- wagtail/images/tasks.py +18 -0
- wagtail/images/templates/wagtailimages/images/edit.html +1 -3
- wagtail/images/templates/wagtailimages/images/url_generator.html +1 -1
- wagtail/images/templates/wagtailimages/multiple/add.html +7 -2
- wagtail/images/templates/wagtailimages/widgets/image_chooser.html +1 -1
- wagtail/images/tests/test_admin_views.py +53 -29
- wagtail/images/tests/test_blocks.py +3 -2
- wagtail/images/tests/test_models.py +12 -10
- wagtail/images/tests/tests.py +10 -0
- wagtail/images/views/chooser.py +1 -0
- wagtail/images/views/images.py +1 -3
- wagtail/images/views/multiple.py +0 -1
- wagtail/images/views/serve.py +18 -2
- wagtail/images/widgets.py +3 -0
- wagtail/locale/en/LC_MESSAGES/django.po +228 -216
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/management/commands/publish_scheduled.py +1 -1
- wagtail/migrations/0087_alter_grouppagepermission_unique_together_and_more.py +16 -8
- wagtail/models/__init__.py +300 -119
- wagtail/models/i18n.py +2 -2
- wagtail/models/panels.py +37 -0
- wagtail/models/sites.py +7 -6
- wagtail/permission_policies/pages.py +2 -2
- wagtail/project_template/project_name/settings/base.py +4 -0
- wagtail/project_template/requirements.txt +1 -1
- wagtail/query.py +145 -0
- wagtail/search/backends/database/mysql/mysql.py +25 -17
- wagtail/search/backends/database/postgres/postgres.py +44 -83
- wagtail/search/backends/database/sqlite/sqlite.py +25 -17
- wagtail/search/backends/elasticsearch7.py +4 -0
- wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/search/query.py +8 -2
- wagtail/search/signal_handlers.py +6 -9
- wagtail/search/tasks.py +10 -0
- wagtail/search/tests/test_elasticsearch7_backend.py +21 -0
- wagtail/search/tests/test_index_functions.py +10 -6
- wagtail/search/tests/test_postgres_backend.py +0 -14
- wagtail/signal_handlers.py +5 -20
- wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +3 -13
- wagtail/snippets/tests/test_preview.py +5 -0
- wagtail/snippets/tests/test_snippets.py +100 -45
- wagtail/snippets/tests/test_usage.py +29 -24
- wagtail/snippets/tests/test_viewset.py +1 -1
- wagtail/snippets/views/snippets.py +0 -12
- wagtail/tasks.py +41 -0
- wagtail/templates/wagtailcore/shared/block_preview.html +29 -0
- wagtail/test/earlypage/__init__.py +0 -0
- wagtail/test/earlypage/migrations/0001_initial.py +37 -0
- wagtail/test/earlypage/migrations/__init__.py +0 -0
- wagtail/test/earlypage/models.py +14 -0
- wagtail/test/settings.py +3 -0
- wagtail/test/testapp/fixtures/test.json +7 -0
- wagtail/test/testapp/fixtures/test_specific.json +6 -3
- wagtail/test/testapp/models.py +58 -44
- wagtail/test/testapp/templates/tests/custom_block_preview.html +16 -0
- wagtail/test/testapp/templates/tests/static_block_preview.html +5 -0
- wagtail/test/testapp/wagtail_hooks.py +9 -0
- wagtail/tests/test_blocks.py +189 -2
- wagtail/tests/test_hooks.py +166 -1
- wagtail/tests/test_management_commands.py +54 -13
- wagtail/tests/test_page_allowed_http_methods.py +32 -0
- wagtail/tests/test_page_model.py +68 -0
- wagtail/tests/test_page_privacy.py +10 -0
- wagtail/tests/test_page_queryset.py +79 -0
- wagtail/tests/test_reference_index.py +84 -75
- wagtail/tests/test_streamfield.py +30 -0
- wagtail/tests/test_utils.py +61 -0
- wagtail/users/forms.py +2 -9
- wagtail/users/locale/en/LC_MESSAGES/django.po +17 -17
- wagtail/users/templates/wagtailusers/groups/create.html +0 -5
- wagtail/users/templates/wagtailusers/groups/includes/page_permissions_form.html +1 -1
- wagtail/users/templates/wagtailusers/groups/includes/page_permissions_formset.html +6 -6
- wagtail/users/tests/test_admin_views.py +96 -4
- wagtail/users/tests/test_utils.py +76 -0
- wagtail/users/utils.py +43 -11
- wagtail/utils/setup.py +2 -2
- wagtail/utils/templates.py +26 -0
- wagtail/utils/widgets.py +1 -0
- wagtail/views.py +9 -1
- wagtail/wagtail_hooks.py +67 -29
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/METADATA +2 -2
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/RECORD +289 -276
- wagtail/admin/static/wagtailadmin/js/expanding-formset.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/rangy-core.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/uuidv4.min.js +0 -1
- wagtail/contrib/search_promotions/views.py +0 -323
- wagtail/images/static/wagtailimages/js/vendor/canvas-to-blob.min.js +0 -1
- wagtail/users/static/wagtailusers/js/group-form.js +0 -1
- wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -3
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.3.2.dist-info → wagtail-6.4rc1.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
from collections import OrderedDict
|
|
2
2
|
from functools import reduce
|
|
3
3
|
|
|
4
|
-
from django.db import
|
|
4
|
+
from django.db import (
|
|
5
|
+
NotSupportedError,
|
|
6
|
+
connections,
|
|
7
|
+
router,
|
|
8
|
+
transaction,
|
|
9
|
+
)
|
|
5
10
|
from django.db.models import Avg, Count, F, Manager, Q, TextField
|
|
6
11
|
from django.db.models.constants import LOOKUP_SEP
|
|
7
12
|
from django.db.models.functions import Cast, Length
|
|
@@ -145,17 +150,22 @@ class ObjectIndexer:
|
|
|
145
150
|
|
|
146
151
|
|
|
147
152
|
class Index:
|
|
148
|
-
def __init__(self, backend
|
|
153
|
+
def __init__(self, backend):
|
|
149
154
|
self.backend = backend
|
|
150
155
|
self.name = self.backend.index_name
|
|
151
|
-
|
|
152
|
-
self.
|
|
153
|
-
|
|
156
|
+
|
|
157
|
+
self.read_connection = connections[router.db_for_read(IndexEntry)]
|
|
158
|
+
self.write_connection = connections[router.db_for_write(IndexEntry)]
|
|
159
|
+
|
|
160
|
+
if (
|
|
161
|
+
self.read_connection.vendor != "sqlite"
|
|
162
|
+
or self.write_connection.vendor != "sqlite"
|
|
163
|
+
):
|
|
154
164
|
raise NotSupportedError(
|
|
155
|
-
"You must select a SQLite database
|
|
165
|
+
"You must select a SQLite database to use the SQLite search backend."
|
|
156
166
|
)
|
|
157
167
|
|
|
158
|
-
self.entries = IndexEntry._default_manager.
|
|
168
|
+
self.entries = IndexEntry._default_manager.all()
|
|
159
169
|
|
|
160
170
|
def add_model(self, model):
|
|
161
171
|
pass
|
|
@@ -195,11 +205,9 @@ class Index:
|
|
|
195
205
|
).update(title_norm=lavg / F("title_length"))
|
|
196
206
|
|
|
197
207
|
def delete_stale_model_entries(self, model):
|
|
198
|
-
existing_pks = (
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
.values("object_id")
|
|
202
|
-
)
|
|
208
|
+
existing_pks = model._default_manager.annotate(
|
|
209
|
+
object_id=Cast("pk", TextField())
|
|
210
|
+
).values("object_id")
|
|
203
211
|
content_types_pks = get_descendants_content_types_pks(model)
|
|
204
212
|
stale_entries = self.entries.filter(
|
|
205
213
|
content_type_id__in=content_types_pks
|
|
@@ -270,7 +278,7 @@ class Index:
|
|
|
270
278
|
update_method(content_type_pk, indexers)
|
|
271
279
|
|
|
272
280
|
def delete_item(self, item):
|
|
273
|
-
item.index_entries.all()._raw_delete(using=self.
|
|
281
|
+
item.index_entries.all()._raw_delete(using=self.write_connection.alias)
|
|
274
282
|
|
|
275
283
|
def __str__(self):
|
|
276
284
|
return self.name
|
|
@@ -291,7 +299,7 @@ class SQLiteSearchRebuilder:
|
|
|
291
299
|
class SQLiteSearchAtomicRebuilder(SQLiteSearchRebuilder):
|
|
292
300
|
def __init__(self, index):
|
|
293
301
|
super().__init__(index)
|
|
294
|
-
self.transaction = transaction.atomic(using=index.
|
|
302
|
+
self.transaction = transaction.atomic(using=index.write_connection.alias)
|
|
295
303
|
self.transaction_opened = False
|
|
296
304
|
|
|
297
305
|
def start(self):
|
|
@@ -673,11 +681,11 @@ class SQLiteSearchBackend(BaseSearchBackend):
|
|
|
673
681
|
if params.get("ATOMIC_REBUILD", False):
|
|
674
682
|
self.rebuilder_class = self.atomic_rebuilder_class
|
|
675
683
|
|
|
676
|
-
def get_index_for_model(self, model
|
|
677
|
-
return Index(self
|
|
684
|
+
def get_index_for_model(self, model):
|
|
685
|
+
return Index(self)
|
|
678
686
|
|
|
679
687
|
def get_index_for_object(self, obj):
|
|
680
|
-
return self.get_index_for_model(obj._meta.model
|
|
688
|
+
return self.get_index_for_model(obj._meta.model)
|
|
681
689
|
|
|
682
690
|
def reset_index(self):
|
|
683
691
|
for connection in [
|
|
@@ -605,6 +605,10 @@ class Elasticsearch7SearchQueryCompiler(BaseSearchQueryCompiler):
|
|
|
605
605
|
"query": query.query_string,
|
|
606
606
|
"fuzziness": "AUTO",
|
|
607
607
|
}
|
|
608
|
+
|
|
609
|
+
if query.operator != "or":
|
|
610
|
+
match_query["operator"] = query.operator
|
|
611
|
+
|
|
608
612
|
if len(fields) == 1:
|
|
609
613
|
if fields[0].boost != 1.0:
|
|
610
614
|
match_query["boost"] = fields[0].boost
|
|
@@ -8,7 +8,7 @@ msgid ""
|
|
|
8
8
|
msgstr ""
|
|
9
9
|
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
10
|
"Report-Msgid-Bugs-To: \n"
|
|
11
|
-
"POT-Creation-Date:
|
|
11
|
+
"POT-Creation-Date: 2025-01-20 17:59+0000\n"
|
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
wagtail/search/query.py
CHANGED
|
@@ -50,11 +50,17 @@ class Phrase(SearchQuery):
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
class Fuzzy(SearchQuery):
|
|
53
|
-
|
|
53
|
+
OPERATORS = ["and", "or"]
|
|
54
|
+
DEFAULT_OPERATOR = "or"
|
|
55
|
+
|
|
56
|
+
def __init__(self, query_string: str, operator: str = DEFAULT_OPERATOR):
|
|
54
57
|
self.query_string = query_string
|
|
58
|
+
self.operator = operator.lower()
|
|
59
|
+
if self.operator not in self.OPERATORS:
|
|
60
|
+
raise ValueError("`operator` must be either 'or' or 'and'.")
|
|
55
61
|
|
|
56
62
|
def __repr__(self):
|
|
57
|
-
return f"<Fuzzy {repr(self.query_string)}>"
|
|
63
|
+
return f"<Fuzzy {repr(self.query_string)} operator={repr(self.operator)}>"
|
|
58
64
|
|
|
59
65
|
|
|
60
66
|
class MatchAll(SearchQuery):
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
from django.db.models.signals import post_delete, post_save
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from . import index
|
|
4
|
+
from .tasks import insert_or_update_object_task
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
def post_save_signal_handler(instance,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# the fields that were not passed in update_fields
|
|
11
|
-
instance = type(instance).objects.get(pk=instance.pk)
|
|
12
|
-
|
|
13
|
-
index.insert_or_update_object(instance)
|
|
7
|
+
def post_save_signal_handler(instance, **kwargs):
|
|
8
|
+
insert_or_update_object_task.enqueue(
|
|
9
|
+
instance._meta.app_label, instance._meta.model_name, instance.pk
|
|
10
|
+
)
|
|
14
11
|
|
|
15
12
|
|
|
16
13
|
def post_delete_signal_handler(instance, **kwargs):
|
wagtail/search/tasks.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from django.apps import apps
|
|
2
|
+
from django_tasks import task
|
|
3
|
+
|
|
4
|
+
from wagtail.search import index
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@task()
|
|
8
|
+
def insert_or_update_object_task(app_label, model_name, pk):
|
|
9
|
+
model = apps.get_model(app_label, model_name)
|
|
10
|
+
index.insert_or_update_object(model.objects.get(pk=pk))
|
|
@@ -840,6 +840,27 @@ class TestElasticsearch7SearchQuery(TestCase):
|
|
|
840
840
|
}
|
|
841
841
|
self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
|
|
842
842
|
|
|
843
|
+
def test_fuzzy_query_with_operator(self):
|
|
844
|
+
# Create a query
|
|
845
|
+
query_compiler = self.query_compiler_class(
|
|
846
|
+
models.Book.objects.all(),
|
|
847
|
+
Fuzzy("Hello world", operator="and"),
|
|
848
|
+
)
|
|
849
|
+
|
|
850
|
+
# Check it
|
|
851
|
+
expected_result = {
|
|
852
|
+
"multi_match": {
|
|
853
|
+
"fields": [
|
|
854
|
+
"_all_text",
|
|
855
|
+
"_all_text_boost_2_0^2.0",
|
|
856
|
+
],
|
|
857
|
+
"query": "Hello world",
|
|
858
|
+
"fuzziness": "AUTO",
|
|
859
|
+
"operator": "and",
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
|
|
863
|
+
|
|
843
864
|
def test_year_filter(self):
|
|
844
865
|
# Create a query
|
|
845
866
|
query_compiler = self.query_compiler_class(
|
|
@@ -160,9 +160,10 @@ class TestRemoveObject(WagtailTestUtils, TestCase):
|
|
|
160
160
|
class TestSignalHandlers(WagtailTestUtils, TestCase):
|
|
161
161
|
def test_index_on_create(self, backend):
|
|
162
162
|
backend().reset_mock()
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
164
|
+
obj = models.Book.objects.create(
|
|
165
|
+
title="Test", publication_date=date(2017, 10, 18), number_of_pages=100
|
|
166
|
+
)
|
|
166
167
|
backend().add.assert_called_with(obj)
|
|
167
168
|
|
|
168
169
|
def test_index_on_update(self, backend):
|
|
@@ -172,7 +173,8 @@ class TestSignalHandlers(WagtailTestUtils, TestCase):
|
|
|
172
173
|
|
|
173
174
|
backend().reset_mock()
|
|
174
175
|
obj.title = "Updated test"
|
|
175
|
-
|
|
176
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
177
|
+
obj.save()
|
|
176
178
|
|
|
177
179
|
self.assertEqual(backend().add.call_count, 1)
|
|
178
180
|
indexed_object = backend().add.call_args[0][0]
|
|
@@ -184,7 +186,8 @@ class TestSignalHandlers(WagtailTestUtils, TestCase):
|
|
|
184
186
|
)
|
|
185
187
|
|
|
186
188
|
backend().reset_mock()
|
|
187
|
-
|
|
189
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
190
|
+
obj.delete()
|
|
188
191
|
backend().delete.assert_called_with(obj)
|
|
189
192
|
|
|
190
193
|
def test_do_not_index_fields_omitted_from_update_fields(self, backend):
|
|
@@ -195,7 +198,8 @@ class TestSignalHandlers(WagtailTestUtils, TestCase):
|
|
|
195
198
|
backend().reset_mock()
|
|
196
199
|
obj.title = "Updated test"
|
|
197
200
|
obj.publication_date = date(2001, 10, 19)
|
|
198
|
-
|
|
201
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
202
|
+
obj.save(update_fields=["title"])
|
|
199
203
|
|
|
200
204
|
self.assertEqual(backend().add.call_count, 1)
|
|
201
205
|
indexed_object = backend().add.call_args[0][0]
|
|
@@ -160,20 +160,6 @@ class TestPostgresSearchBackend(BackendTests, TestCase):
|
|
|
160
160
|
results = self.backend.autocomplete("first <-> second", models.Book)
|
|
161
161
|
self.assertUnsortedListEqual([r.title for r in results], [])
|
|
162
162
|
|
|
163
|
-
def test_index_without_upsert(self):
|
|
164
|
-
# Test the add_items code path for Postgres 9.4, where upsert is not available
|
|
165
|
-
self.backend.reset_index()
|
|
166
|
-
|
|
167
|
-
index = self.backend.get_index_for_model(models.Book)
|
|
168
|
-
index._enable_upsert = False
|
|
169
|
-
index.add_items(models.Book, models.Book.objects.all())
|
|
170
|
-
|
|
171
|
-
results = self.backend.search("JavaScript", models.Book)
|
|
172
|
-
self.assertUnsortedListEqual(
|
|
173
|
-
[r.title for r in results],
|
|
174
|
-
["JavaScript: The good parts", "JavaScript: The Definitive Guide"],
|
|
175
|
-
)
|
|
176
|
-
|
|
177
163
|
|
|
178
164
|
@unittest.skipUnless(
|
|
179
165
|
connection.vendor == "postgresql", "The current database is not PostgreSQL"
|
wagtail/signal_handlers.py
CHANGED
|
@@ -11,10 +11,11 @@ from django.db.models.signals import (
|
|
|
11
11
|
pre_delete,
|
|
12
12
|
pre_migrate,
|
|
13
13
|
)
|
|
14
|
-
from modelcluster.fields import ParentalKey
|
|
15
14
|
|
|
16
15
|
from wagtail.models import Locale, Page, ReferenceIndex, Site
|
|
17
16
|
|
|
17
|
+
from .tasks import update_reference_index_task
|
|
18
|
+
|
|
18
19
|
logger = logging.getLogger("wagtail")
|
|
19
20
|
|
|
20
21
|
|
|
@@ -70,25 +71,9 @@ def update_reference_index_on_save(instance, **kwargs):
|
|
|
70
71
|
if getattr(reference_index_auto_update_disabled, "value", False):
|
|
71
72
|
return
|
|
72
73
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
filter(
|
|
77
|
-
lambda field: isinstance(field, ParentalKey),
|
|
78
|
-
instance._meta.get_fields(),
|
|
79
|
-
)
|
|
80
|
-
)
|
|
81
|
-
if not parental_keys:
|
|
82
|
-
break
|
|
83
|
-
|
|
84
|
-
instance = getattr(instance, parental_keys[0].name)
|
|
85
|
-
if instance is None:
|
|
86
|
-
# parent is null, so there is no valid object to record references against
|
|
87
|
-
return
|
|
88
|
-
|
|
89
|
-
if ReferenceIndex.is_indexed(instance._meta.model):
|
|
90
|
-
with transaction.atomic():
|
|
91
|
-
ReferenceIndex.create_or_update_for_object(instance)
|
|
74
|
+
update_reference_index_task.enqueue(
|
|
75
|
+
instance._meta.app_label, instance._meta.model_name, instance.pk
|
|
76
|
+
)
|
|
92
77
|
|
|
93
78
|
|
|
94
79
|
def remove_reference_index_on_delete(instance, **kwargs):
|
|
@@ -8,7 +8,7 @@ msgid ""
|
|
|
8
8
|
msgstr ""
|
|
9
9
|
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
10
|
"Report-Msgid-Bugs-To: \n"
|
|
11
|
-
"POT-Creation-Date:
|
|
11
|
+
"POT-Creation-Date: 2025-01-20 17:59+0000\n"
|
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
@@ -8,7 +8,7 @@ msgid ""
|
|
|
8
8
|
msgstr ""
|
|
9
9
|
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
10
|
"Report-Msgid-Bugs-To: \n"
|
|
11
|
-
"POT-Creation-Date:
|
|
11
|
+
"POT-Creation-Date: 2025-01-20 17:59+0000\n"
|
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
@@ -177,7 +177,7 @@ msgstr ""
|
|
|
177
177
|
msgid "Choose"
|
|
178
178
|
msgstr ""
|
|
179
179
|
|
|
180
|
-
#: views/snippets.py:76 views/snippets.py:
|
|
180
|
+
#: views/snippets.py:76 views/snippets.py:870 wagtail_hooks.py:42
|
|
181
181
|
msgid "Snippets"
|
|
182
182
|
msgstr ""
|
|
183
183
|
|
|
@@ -194,17 +194,7 @@ msgstr ""
|
|
|
194
194
|
msgid "More options for '%(title)s'"
|
|
195
195
|
msgstr ""
|
|
196
196
|
|
|
197
|
-
#: views/snippets.py:
|
|
198
|
-
#, python-format
|
|
199
|
-
msgid "Edit this %(model_name)s"
|
|
200
|
-
msgstr ""
|
|
201
|
-
|
|
202
|
-
#: views/snippets.py:369
|
|
203
|
-
#, python-format
|
|
204
|
-
msgid "%(model_name)s history"
|
|
205
|
-
msgstr ""
|
|
206
|
-
|
|
207
|
-
#: views/snippets.py:881
|
|
197
|
+
#: views/snippets.py:869
|
|
208
198
|
msgid "Home"
|
|
209
199
|
msgstr ""
|
|
210
200
|
|
|
@@ -5,6 +5,7 @@ from django.urls import reverse
|
|
|
5
5
|
from django.utils import timezone
|
|
6
6
|
from freezegun import freeze_time
|
|
7
7
|
|
|
8
|
+
from wagtail.admin.staticfiles import versioned_static
|
|
8
9
|
from wagtail.admin.views.generic.preview import PreviewOnEdit
|
|
9
10
|
from wagtail.test.testapp.models import (
|
|
10
11
|
EventCategory,
|
|
@@ -59,6 +60,7 @@ class TestPreview(WagtailTestUtils, TestCase):
|
|
|
59
60
|
'<h1 class="preview-error__title">Preview not available</h1>',
|
|
60
61
|
html=True,
|
|
61
62
|
)
|
|
63
|
+
self.assertNotContains(response, versioned_static("wagtailadmin/js/icons.js"))
|
|
62
64
|
|
|
63
65
|
def test_preview_on_create_with_invalid_data(self):
|
|
64
66
|
self.assertNotIn(self.session_key_prefix, self.client.session)
|
|
@@ -90,6 +92,7 @@ class TestPreview(WagtailTestUtils, TestCase):
|
|
|
90
92
|
'<h1 class="preview-error__title">Preview not available</h1>',
|
|
91
93
|
html=True,
|
|
92
94
|
)
|
|
95
|
+
self.assertNotContains(response, versioned_static("wagtailadmin/js/icons.js"))
|
|
93
96
|
|
|
94
97
|
def test_preview_on_create_with_m2m_field(self):
|
|
95
98
|
response = self.client.post(self.preview_on_add_url, self.post_data)
|
|
@@ -229,6 +232,7 @@ class TestPreview(WagtailTestUtils, TestCase):
|
|
|
229
232
|
'<h1 class="preview-error__title">Preview not available</h1>',
|
|
230
233
|
html=True,
|
|
231
234
|
)
|
|
235
|
+
self.assertNotContains(response, versioned_static("wagtailadmin/js/icons.js"))
|
|
232
236
|
|
|
233
237
|
def test_preview_on_edit_clear_preview_data(self):
|
|
234
238
|
# Set a fake preview session data for the page
|
|
@@ -259,6 +263,7 @@ class TestPreview(WagtailTestUtils, TestCase):
|
|
|
259
263
|
'<h1 class="preview-error__title">Preview not available</h1>',
|
|
260
264
|
html=True,
|
|
261
265
|
)
|
|
266
|
+
self.assertNotContains(response, versioned_static("wagtailadmin/js/icons.js"))
|
|
262
267
|
|
|
263
268
|
def test_preview_revision(self):
|
|
264
269
|
snippet = MultiPreviewModesModel.objects.create(text="Multiple modes")
|
|
@@ -4129,9 +4129,10 @@ class TestSnippetDelete(WagtailTestUtils, TestCase):
|
|
|
4129
4129
|
self.assertContains(response, delete_url)
|
|
4130
4130
|
|
|
4131
4131
|
def test_delete_get_with_protected_reference(self):
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4132
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
4133
|
+
VariousOnDeleteModel.objects.create(
|
|
4134
|
+
text="Undeletable", on_delete_protect=self.test_snippet
|
|
4135
|
+
)
|
|
4135
4136
|
delete_url = reverse(
|
|
4136
4137
|
"wagtailsnippets_tests_advert:delete",
|
|
4137
4138
|
args=[quote(self.test_snippet.pk)],
|
|
@@ -4186,9 +4187,10 @@ class TestSnippetDelete(WagtailTestUtils, TestCase):
|
|
|
4186
4187
|
self.assertEqual(Advert.objects.filter(text="test_advert").count(), 0)
|
|
4187
4188
|
|
|
4188
4189
|
def test_delete_post_with_protected_reference(self):
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4190
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
4191
|
+
VariousOnDeleteModel.objects.create(
|
|
4192
|
+
text="Undeletable", on_delete_protect=self.test_snippet
|
|
4193
|
+
)
|
|
4192
4194
|
delete_url = reverse(
|
|
4193
4195
|
"wagtailsnippets_tests_advert:delete",
|
|
4194
4196
|
args=[quote(self.test_snippet.pk)],
|
|
@@ -4870,7 +4872,7 @@ class TestSnippetRevisions(WagtailTestUtils, TestCase):
|
|
|
4870
4872
|
self.assertEqual(self.snippet.live_revision, self.snippet.latest_revision)
|
|
4871
4873
|
|
|
4872
4874
|
|
|
4873
|
-
class TestCompareRevisions(WagtailTestUtils, TestCase):
|
|
4875
|
+
class TestCompareRevisions(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
|
|
4874
4876
|
# Actual tests for the comparison classes can be found in test_compare.py
|
|
4875
4877
|
|
|
4876
4878
|
def setUp(self):
|
|
@@ -4908,6 +4910,32 @@ class TestCompareRevisions(WagtailTestUtils, TestCase):
|
|
|
4908
4910
|
html=True,
|
|
4909
4911
|
)
|
|
4910
4912
|
|
|
4913
|
+
index_url = reverse("wagtailsnippets_tests_revisablemodel:list", args=[])
|
|
4914
|
+
edit_url = reverse(
|
|
4915
|
+
"wagtailsnippets_tests_revisablemodel:edit",
|
|
4916
|
+
args=(self.snippet.id,),
|
|
4917
|
+
)
|
|
4918
|
+
history_url = reverse(
|
|
4919
|
+
"wagtailsnippets_tests_revisablemodel:history",
|
|
4920
|
+
args=(self.snippet.id,),
|
|
4921
|
+
)
|
|
4922
|
+
|
|
4923
|
+
self.assertBreadcrumbsItemsRendered(
|
|
4924
|
+
[
|
|
4925
|
+
{"url": reverse("wagtailsnippets:index"), "label": "Snippets"},
|
|
4926
|
+
{"url": index_url, "label": "Revisable models"},
|
|
4927
|
+
{"url": edit_url, "label": str(self.snippet)},
|
|
4928
|
+
{"url": history_url, "label": "History"},
|
|
4929
|
+
{"url": "", "label": "Compare", "sublabel": str(self.snippet)},
|
|
4930
|
+
],
|
|
4931
|
+
response.content,
|
|
4932
|
+
)
|
|
4933
|
+
|
|
4934
|
+
soup = self.get_soup(response.content)
|
|
4935
|
+
edit_button = soup.select_one(f"a.w-header-button[href='{edit_url}']")
|
|
4936
|
+
self.assertIsNotNone(edit_button)
|
|
4937
|
+
self.assertEqual(edit_button.text.strip(), "Edit")
|
|
4938
|
+
|
|
4911
4939
|
def test_compare_revisions_earliest(self):
|
|
4912
4940
|
response = self.get("earliest", self.edit_revision.pk)
|
|
4913
4941
|
self.assertEqual(response.status_code, 200)
|
|
@@ -5496,7 +5524,11 @@ class TestSnippetChooserBlock(TestCase):
|
|
|
5496
5524
|
self.assertEqual(block.to_python(test_advert.id), test_advert)
|
|
5497
5525
|
|
|
5498
5526
|
def test_adapt(self):
|
|
5499
|
-
block = SnippetChooserBlock(
|
|
5527
|
+
block = SnippetChooserBlock(
|
|
5528
|
+
Advert,
|
|
5529
|
+
help_text="pick an advert, any advert",
|
|
5530
|
+
description="An advert to be displayed on the sidebar.",
|
|
5531
|
+
)
|
|
5500
5532
|
|
|
5501
5533
|
block.set_name("test_snippetchooserblock")
|
|
5502
5534
|
js_args = FieldBlockAdapter().js_args(block)
|
|
@@ -5508,8 +5540,11 @@ class TestSnippetChooserBlock(TestCase):
|
|
|
5508
5540
|
js_args[2],
|
|
5509
5541
|
{
|
|
5510
5542
|
"label": "Test snippetchooserblock",
|
|
5543
|
+
"description": "An advert to be displayed on the sidebar.",
|
|
5511
5544
|
"required": True,
|
|
5512
5545
|
"icon": "snippet",
|
|
5546
|
+
"blockDefId": block.definition_prefix,
|
|
5547
|
+
"isPreviewable": block.is_previewable,
|
|
5513
5548
|
"helpText": "pick an advert, any advert",
|
|
5514
5549
|
"classname": "w-field w-field--model_choice_field w-field--admin_snippet_chooser",
|
|
5515
5550
|
"showAddCommentButton": True,
|
|
@@ -5622,6 +5657,9 @@ class TestSnippetViewWithCustomPrimaryKey(WagtailTestUtils, TestCase):
|
|
|
5622
5657
|
self.snippet_a = StandardSnippetWithCustomPrimaryKey.objects.create(
|
|
5623
5658
|
snippet_id="snippet/01", text="Hello"
|
|
5624
5659
|
)
|
|
5660
|
+
self.snippet_b = StandardSnippetWithCustomPrimaryKey.objects.create(
|
|
5661
|
+
snippet_id="abc_407269_1", text="Goodbye"
|
|
5662
|
+
)
|
|
5625
5663
|
|
|
5626
5664
|
def get(self, snippet, params={}):
|
|
5627
5665
|
args = [quote(snippet.pk)]
|
|
@@ -5644,9 +5682,11 @@ class TestSnippetViewWithCustomPrimaryKey(WagtailTestUtils, TestCase):
|
|
|
5644
5682
|
)
|
|
5645
5683
|
|
|
5646
5684
|
def test_show_edit_view(self):
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5685
|
+
for snippet in [self.snippet_a, self.snippet_b]:
|
|
5686
|
+
with self.subTest(snippet=snippet):
|
|
5687
|
+
response = self.get(snippet)
|
|
5688
|
+
self.assertEqual(response.status_code, 200)
|
|
5689
|
+
self.assertTemplateUsed(response, "wagtailsnippets/snippets/edit.html")
|
|
5650
5690
|
|
|
5651
5691
|
def test_edit_invalid(self):
|
|
5652
5692
|
response = self.post(self.snippet_a, post_data={"foo": "bar"})
|
|
@@ -5669,8 +5709,10 @@ class TestSnippetViewWithCustomPrimaryKey(WagtailTestUtils, TestCase):
|
|
|
5669
5709
|
)
|
|
5670
5710
|
|
|
5671
5711
|
snippets = StandardSnippetWithCustomPrimaryKey.objects.all()
|
|
5672
|
-
self.assertEqual(snippets.count(),
|
|
5673
|
-
self.assertEqual(
|
|
5712
|
+
self.assertEqual(snippets.count(), 3)
|
|
5713
|
+
self.assertEqual(
|
|
5714
|
+
snippets.order_by("snippet_id").last().snippet_id, "snippet_id_edited"
|
|
5715
|
+
)
|
|
5674
5716
|
|
|
5675
5717
|
def test_create(self):
|
|
5676
5718
|
response = self.create(
|
|
@@ -5685,40 +5727,48 @@ class TestSnippetViewWithCustomPrimaryKey(WagtailTestUtils, TestCase):
|
|
|
5685
5727
|
)
|
|
5686
5728
|
|
|
5687
5729
|
snippets = StandardSnippetWithCustomPrimaryKey.objects.all()
|
|
5688
|
-
self.assertEqual(snippets.count(),
|
|
5689
|
-
self.assertEqual(snippets.last().text, "test snippet")
|
|
5730
|
+
self.assertEqual(snippets.count(), 3)
|
|
5731
|
+
self.assertEqual(snippets.order_by("snippet_id").last().text, "test snippet")
|
|
5690
5732
|
|
|
5691
5733
|
def test_get_delete(self):
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5734
|
+
for snippet in [self.snippet_a, self.snippet_b]:
|
|
5735
|
+
with self.subTest(snippet=snippet):
|
|
5736
|
+
response = self.client.get(
|
|
5737
|
+
reverse(
|
|
5738
|
+
"wagtailsnippets_snippetstests_standardsnippetwithcustomprimarykey:delete",
|
|
5739
|
+
args=[quote(snippet.pk)],
|
|
5740
|
+
)
|
|
5741
|
+
)
|
|
5742
|
+
self.assertEqual(response.status_code, 200)
|
|
5743
|
+
self.assertTemplateUsed(
|
|
5744
|
+
response, "wagtailadmin/generic/confirm_delete.html"
|
|
5745
|
+
)
|
|
5700
5746
|
|
|
5701
5747
|
def test_usage_link(self):
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5748
|
+
for snippet in [self.snippet_a, self.snippet_b]:
|
|
5749
|
+
with self.subTest(snippet=snippet):
|
|
5750
|
+
response = self.client.get(
|
|
5751
|
+
reverse(
|
|
5752
|
+
"wagtailsnippets_snippetstests_standardsnippetwithcustomprimarykey:delete",
|
|
5753
|
+
args=[quote(snippet.pk)],
|
|
5754
|
+
)
|
|
5755
|
+
)
|
|
5756
|
+
self.assertEqual(response.status_code, 200)
|
|
5757
|
+
self.assertTemplateUsed(
|
|
5758
|
+
response, "wagtailadmin/generic/confirm_delete.html"
|
|
5759
|
+
)
|
|
5760
|
+
self.assertContains(
|
|
5761
|
+
response,
|
|
5762
|
+
"This standard snippet with custom primary key is referenced 0 times",
|
|
5763
|
+
)
|
|
5764
|
+
self.assertContains(
|
|
5765
|
+
response,
|
|
5766
|
+
reverse(
|
|
5767
|
+
"wagtailsnippets_snippetstests_standardsnippetwithcustomprimarykey:usage",
|
|
5768
|
+
args=[quote(snippet.pk)],
|
|
5769
|
+
)
|
|
5770
|
+
+ "?describe_on_delete=1",
|
|
5771
|
+
)
|
|
5722
5772
|
|
|
5723
5773
|
def test_redirect_to_edit(self):
|
|
5724
5774
|
with self.assertWarnsRegex(
|
|
@@ -5788,7 +5838,9 @@ class TestSnippetChooserBlockWithCustomPrimaryKey(TestCase):
|
|
|
5788
5838
|
|
|
5789
5839
|
def test_adapt(self):
|
|
5790
5840
|
block = SnippetChooserBlock(
|
|
5791
|
-
AdvertWithCustomPrimaryKey,
|
|
5841
|
+
AdvertWithCustomPrimaryKey,
|
|
5842
|
+
help_text="pick an advert, any advert",
|
|
5843
|
+
description="An advert to be displayed on the footer.",
|
|
5792
5844
|
)
|
|
5793
5845
|
|
|
5794
5846
|
block.set_name("test_snippetchooserblock")
|
|
@@ -5801,8 +5853,11 @@ class TestSnippetChooserBlockWithCustomPrimaryKey(TestCase):
|
|
|
5801
5853
|
js_args[2],
|
|
5802
5854
|
{
|
|
5803
5855
|
"label": "Test snippetchooserblock",
|
|
5856
|
+
"description": "An advert to be displayed on the footer.",
|
|
5804
5857
|
"required": True,
|
|
5805
5858
|
"icon": "snippet",
|
|
5859
|
+
"blockDefId": block.definition_prefix,
|
|
5860
|
+
"isPreviewable": block.is_previewable,
|
|
5806
5861
|
"helpText": "pick an advert, any advert",
|
|
5807
5862
|
"classname": "w-field w-field--model_choice_field w-field--admin_snippet_chooser",
|
|
5808
5863
|
"showAddCommentButton": True,
|
|
@@ -6000,7 +6055,7 @@ class TestPanelConfigurationChecks(WagtailTestUtils, TestCase):
|
|
|
6000
6055
|
|
|
6001
6056
|
warning = checks.Warning(
|
|
6002
6057
|
"StandardSnippet.content_panels will have no effect on snippets editing",
|
|
6003
|
-
hint="""Ensure that StandardSnippet uses `panels` instead of `content_panels
|
|
6058
|
+
hint="""Ensure that StandardSnippet uses `panels` instead of `content_panels` \
|
|
6004
6059
|
or set up an `edit_handler` if you want a tabbed editing interface.
|
|
6005
6060
|
There are no default tabs on non-Page models so there will be no\
|
|
6006
6061
|
Content tab for the content_panels to render in.""",
|