wagtail 6.3.1__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/locale/gl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/gl/LC_MESSAGES/djangojs.po +5 -5
- wagtail/admin/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pt_BR/LC_MESSAGES/django.po +29 -0
- 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/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/gl/LC_MESSAGES/django.po +4 -4
- wagtail/contrib/forms/tests/test_models.py +7 -5
- wagtail/contrib/forms/tests/test_views.py +75 -0
- wagtail/contrib/frontend_cache/backends/cloudfront.py +1 -1
- wagtail/contrib/frontend_cache/tasks.py +83 -0
- wagtail/contrib/frontend_cache/tests.py +48 -33
- 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 +14 -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 +34 -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/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/sv/LC_MESSAGES/django.po +4 -3
- 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/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/nl/LC_MESSAGES/django.po +4 -3
- 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.1.dist-info → wagtail-6.4rc1.dist-info}/METADATA +2 -2
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/RECORD +300 -287
- 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.1.dist-info → wagtail-6.4rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.3.1.dist-info → wagtail-6.4rc1.dist-info}/top_level.txt +0 -0
|
@@ -74,15 +74,16 @@ class TestSnippetUsageView(WagtailTestUtils, TestCase):
|
|
|
74
74
|
self.assertEqual(sublabel.get_text(strip=True), "Draft-enabled Bar, In Draft")
|
|
75
75
|
|
|
76
76
|
def test_usage(self):
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
77
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
78
|
+
# resave so that usage count gets updated
|
|
79
|
+
page = Page.objects.get(pk=2)
|
|
80
|
+
page.save()
|
|
81
|
+
|
|
82
|
+
gfk_page = GenericSnippetPage(
|
|
83
|
+
title="Foobar Title",
|
|
84
|
+
snippet_content_object=Advert.objects.get(pk=1),
|
|
85
|
+
)
|
|
86
|
+
page.add_child(instance=gfk_page)
|
|
86
87
|
|
|
87
88
|
response = self.client.get(
|
|
88
89
|
reverse(
|
|
@@ -124,9 +125,10 @@ class TestSnippetUsageView(WagtailTestUtils, TestCase):
|
|
|
124
125
|
self.assertRedirects(response, reverse("wagtailadmin_home"))
|
|
125
126
|
|
|
126
127
|
def test_usage_without_edit_permission_on_page(self):
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
129
|
+
# resave so that usage count gets updated
|
|
130
|
+
page = Page.objects.get(pk=2)
|
|
131
|
+
page.save()
|
|
130
132
|
|
|
131
133
|
# Create a user with edit access to snippets but not pages
|
|
132
134
|
user = self.create_user(
|
|
@@ -157,9 +159,10 @@ class TestSnippetUsageView(WagtailTestUtils, TestCase):
|
|
|
157
159
|
self.assertContains(response, "<li>Advert</li>", html=True)
|
|
158
160
|
|
|
159
161
|
def test_usage_with_describe_on_delete_cascade(self):
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
163
|
+
# resave so that usage count gets updated
|
|
164
|
+
page = Page.objects.get(pk=2)
|
|
165
|
+
page.save()
|
|
163
166
|
|
|
164
167
|
response = self.client.get(
|
|
165
168
|
reverse("wagtailsnippets_tests_advert:usage", args=["1"])
|
|
@@ -173,9 +176,10 @@ class TestSnippetUsageView(WagtailTestUtils, TestCase):
|
|
|
173
176
|
self.assertContains(response, ": the advert placement will also be deleted")
|
|
174
177
|
|
|
175
178
|
def test_usage_with_describe_on_delete_set_null(self):
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
180
|
+
# resave so that usage count gets updated
|
|
181
|
+
page = EventPage.objects.first()
|
|
182
|
+
page.save()
|
|
179
183
|
|
|
180
184
|
self.assertEqual(page.feed_image.get_usage().count(), 1)
|
|
181
185
|
|
|
@@ -191,13 +195,14 @@ class TestSnippetUsageView(WagtailTestUtils, TestCase):
|
|
|
191
195
|
self.assertContains(response, ": will unset the reference")
|
|
192
196
|
|
|
193
197
|
def test_usage_with_describe_on_delete_gfk(self):
|
|
194
|
-
|
|
198
|
+
with self.captureOnCommitCallbacks(execute=True):
|
|
199
|
+
advert = Advert.objects.get(pk=1)
|
|
195
200
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
+
gfk_page = GenericSnippetPage(
|
|
202
|
+
title="Foobar Title",
|
|
203
|
+
snippet_content_object=advert,
|
|
204
|
+
)
|
|
205
|
+
Page.objects.get(pk=1).add_child(instance=gfk_page)
|
|
201
206
|
|
|
202
207
|
self.assertEqual(ReferenceIndex.get_grouped_references_to(advert).count(), 1)
|
|
203
208
|
|
|
@@ -358,18 +358,6 @@ class PreviewRevisionView(PermissionCheckedMixin, PreviewRevision):
|
|
|
358
358
|
class RevisionsCompareView(PermissionCheckedMixin, generic.RevisionsCompareView):
|
|
359
359
|
permission_required = "change"
|
|
360
360
|
|
|
361
|
-
@property
|
|
362
|
-
def edit_label(self):
|
|
363
|
-
return _("Edit this %(model_name)s") % {
|
|
364
|
-
"model_name": self.model._meta.verbose_name
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
@property
|
|
368
|
-
def history_label(self):
|
|
369
|
-
return _("%(model_name)s history") % {
|
|
370
|
-
"model_name": self.model._meta.verbose_name
|
|
371
|
-
}
|
|
372
|
-
|
|
373
361
|
|
|
374
362
|
class UnpublishView(PermissionCheckedMixin, generic.UnpublishView):
|
|
375
363
|
permission_required = "publish"
|
wagtail/tasks.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from django.apps import apps
|
|
2
|
+
from django.db import transaction
|
|
3
|
+
from django.utils.module_loading import import_string
|
|
4
|
+
from django_tasks import task
|
|
5
|
+
from modelcluster.fields import ParentalKey
|
|
6
|
+
|
|
7
|
+
from wagtail.models import ReferenceIndex
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@task()
|
|
11
|
+
def update_reference_index_task(app_label, model_name, pk):
|
|
12
|
+
model = apps.get_model(app_label, model_name)
|
|
13
|
+
instance = model.objects.get(pk=pk)
|
|
14
|
+
|
|
15
|
+
# If the model is a child model, find the parent instance and index that instead
|
|
16
|
+
while True:
|
|
17
|
+
parental_keys = list(
|
|
18
|
+
filter(
|
|
19
|
+
lambda field: isinstance(field, ParentalKey),
|
|
20
|
+
instance._meta.get_fields(),
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
if not parental_keys:
|
|
24
|
+
break
|
|
25
|
+
|
|
26
|
+
instance = getattr(instance, parental_keys[0].name)
|
|
27
|
+
if instance is None:
|
|
28
|
+
# parent is null, so there is no valid object to record references against
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
if ReferenceIndex.is_indexed(instance._meta.model):
|
|
32
|
+
with transaction.atomic():
|
|
33
|
+
ReferenceIndex.create_or_update_for_object(instance)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@task()
|
|
37
|
+
def delete_file_from_storage_task(deconstructed_storage, path):
|
|
38
|
+
storage_module, storage_args, storage_kwargs = deconstructed_storage
|
|
39
|
+
storage = import_string(storage_module)(*storage_args, **storage_kwargs)
|
|
40
|
+
|
|
41
|
+
storage.delete(path)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{% load wagtailcore_tags i18n %}
|
|
2
|
+
{% get_current_language as LANGUAGE_CODE %}
|
|
3
|
+
{% get_current_language_bidi as LANGUAGE_BIDI %}
|
|
4
|
+
<!DOCTYPE html>
|
|
5
|
+
<html lang="{{ LANGUAGE_CODE }}" dir="{% if LANGUAGE_BIDI %}rtl{% else %}ltr{% endif %}">
|
|
6
|
+
<head>
|
|
7
|
+
{% block head %}
|
|
8
|
+
<meta charset="UTF-8" />
|
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
10
|
+
<meta name="robots" content="noindex" />
|
|
11
|
+
<title>{{ page_title }}</title>
|
|
12
|
+
|
|
13
|
+
{% block css %}
|
|
14
|
+
{% endblock %}
|
|
15
|
+
{% endblock %}
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
{% block body %}
|
|
19
|
+
<main>
|
|
20
|
+
{% block content %}
|
|
21
|
+
{% include_block bound_block %}
|
|
22
|
+
{% endblock %}
|
|
23
|
+
</main>
|
|
24
|
+
|
|
25
|
+
{% block js %}
|
|
26
|
+
{% endblock %}
|
|
27
|
+
{% endblock %}
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
|
File without changes
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Generated by Django 5.1.4 on 2025-01-03 15:30
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
initial = True
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
("wagtailcore", "0094_alter_page_locale"),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
operations = [
|
|
16
|
+
migrations.CreateModel(
|
|
17
|
+
name="EarlyPage",
|
|
18
|
+
fields=[
|
|
19
|
+
(
|
|
20
|
+
"page_ptr",
|
|
21
|
+
models.OneToOneField(
|
|
22
|
+
auto_created=True,
|
|
23
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
24
|
+
parent_link=True,
|
|
25
|
+
primary_key=True,
|
|
26
|
+
serialize=False,
|
|
27
|
+
to="wagtailcore.page",
|
|
28
|
+
),
|
|
29
|
+
),
|
|
30
|
+
("intro", models.TextField(blank=True)),
|
|
31
|
+
],
|
|
32
|
+
options={
|
|
33
|
+
"abstract": False,
|
|
34
|
+
},
|
|
35
|
+
bases=("wagtailcore.page",),
|
|
36
|
+
),
|
|
37
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# This module DOES NOT import from wagtail.admin -
|
|
2
|
+
# this tests that we are able to define Page models before wagtail.admin is loaded.
|
|
3
|
+
|
|
4
|
+
from django.db import models
|
|
5
|
+
|
|
6
|
+
from wagtail.models import Page
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EarlyPage(Page):
|
|
10
|
+
intro = models.TextField(blank=True)
|
|
11
|
+
|
|
12
|
+
content_panels = Page.content_panels + [
|
|
13
|
+
"intro",
|
|
14
|
+
]
|
wagtail/test/settings.py
CHANGED
|
@@ -135,6 +135,9 @@ MIDDLEWARE = (
|
|
|
135
135
|
)
|
|
136
136
|
|
|
137
137
|
INSTALLED_APPS = [
|
|
138
|
+
# Place wagtail.test.earlypage first, to test the behaviour of page models
|
|
139
|
+
# that are defined before wagtail.admin is loaded
|
|
140
|
+
"wagtail.test.earlypage",
|
|
138
141
|
# Install wagtailredirects with its appconfig
|
|
139
142
|
# There's nothing special about wagtailredirects, we just need to have one
|
|
140
143
|
# app which uses AppConfigs to test that hooks load properly
|
|
@@ -1027,5 +1027,12 @@
|
|
|
1027
1027
|
"fields": {
|
|
1028
1028
|
"content": "non-url-safe pk modelwithstringtypeprimarykey model"
|
|
1029
1029
|
}
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
"pk": "web_407269_1",
|
|
1033
|
+
"model": "tests.modelwithstringtypeprimarykey",
|
|
1034
|
+
"fields": {
|
|
1035
|
+
"content": "unquote-sensitive modelwithstringtypeprimarykey model"
|
|
1036
|
+
}
|
|
1030
1037
|
}
|
|
1031
1038
|
]
|
|
@@ -141,7 +141,8 @@
|
|
|
141
141
|
"audience": "public",
|
|
142
142
|
"location": "The moon",
|
|
143
143
|
"body": "<p>I haven't worked out the details yet, but it's going to have cake and ponies</p>",
|
|
144
|
-
"cost": "Free"
|
|
144
|
+
"cost": "Free",
|
|
145
|
+
"feed_image": 1
|
|
145
146
|
}
|
|
146
147
|
},
|
|
147
148
|
|
|
@@ -170,7 +171,8 @@
|
|
|
170
171
|
"audience": "private",
|
|
171
172
|
"location": "The moon",
|
|
172
173
|
"body": "<p>your name's not down, you're not coming in</p>",
|
|
173
|
-
"cost": "Free (but not for you)"
|
|
174
|
+
"cost": "Free (but not for you)",
|
|
175
|
+
"feed_image": 1
|
|
174
176
|
}
|
|
175
177
|
},
|
|
176
178
|
|
|
@@ -246,7 +248,8 @@
|
|
|
246
248
|
"audience": "public",
|
|
247
249
|
"location": "Hobart",
|
|
248
250
|
"body": "<p>Party time</p>",
|
|
249
|
-
"cost": "free"
|
|
251
|
+
"cost": "free",
|
|
252
|
+
"feed_image": 1
|
|
250
253
|
}
|
|
251
254
|
},
|
|
252
255
|
|
wagtail/test/testapp/models.py
CHANGED
|
@@ -44,7 +44,8 @@ from wagtail.blocks import (
|
|
|
44
44
|
StreamBlock,
|
|
45
45
|
StructBlock,
|
|
46
46
|
)
|
|
47
|
-
from wagtail.
|
|
47
|
+
from wagtail.compat import HTTPMethod
|
|
48
|
+
from wagtail.contrib.forms.forms import FormBuilder, WagtailAdminFormPageForm
|
|
48
49
|
from wagtail.contrib.forms.models import (
|
|
49
50
|
FORM_FIELD_CHOICES,
|
|
50
51
|
AbstractEmailForm,
|
|
@@ -93,12 +94,7 @@ EVENT_AUDIENCE_CHOICES = (
|
|
|
93
94
|
)
|
|
94
95
|
|
|
95
96
|
|
|
96
|
-
COMMON_PANELS = (
|
|
97
|
-
FieldPanel("slug"),
|
|
98
|
-
FieldPanel("seo_title"),
|
|
99
|
-
FieldPanel("show_in_menus"),
|
|
100
|
-
FieldPanel("search_description"),
|
|
101
|
-
)
|
|
97
|
+
COMMON_PANELS = ("slug", "seo_title", "show_in_menus", "search_description")
|
|
102
98
|
|
|
103
99
|
CUSTOM_PREVIEW_SIZES = [
|
|
104
100
|
{
|
|
@@ -170,9 +166,9 @@ class CarouselItem(LinkFields):
|
|
|
170
166
|
caption = models.CharField(max_length=255, blank=True)
|
|
171
167
|
|
|
172
168
|
panels = [
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
169
|
+
"image",
|
|
170
|
+
"embed_url",
|
|
171
|
+
"caption",
|
|
176
172
|
MultiFieldPanel(LinkFields.panels, "Link"),
|
|
177
173
|
]
|
|
178
174
|
|
|
@@ -187,7 +183,7 @@ class RelatedLink(LinkFields):
|
|
|
187
183
|
title = models.CharField(max_length=255, help_text="Link title")
|
|
188
184
|
|
|
189
185
|
panels = [
|
|
190
|
-
|
|
186
|
+
"title",
|
|
191
187
|
MultiFieldPanel(LinkFields.panels, "Link"),
|
|
192
188
|
]
|
|
193
189
|
|
|
@@ -320,10 +316,7 @@ class EventPageSpeakerAward(TranslatableMixin, Orderable, models.Model):
|
|
|
320
316
|
name = models.CharField("Award name", max_length=255)
|
|
321
317
|
date_awarded = models.DateField(null=True, blank=True)
|
|
322
318
|
|
|
323
|
-
panels = [
|
|
324
|
-
FieldPanel("name"),
|
|
325
|
-
FieldPanel("date_awarded"),
|
|
326
|
-
]
|
|
319
|
+
panels = ["name", "date_awarded"]
|
|
327
320
|
|
|
328
321
|
class Meta(TranslatableMixin.Meta, Orderable.Meta):
|
|
329
322
|
pass
|
|
@@ -351,9 +344,9 @@ class EventPageSpeaker(TranslatableMixin, Orderable, LinkFields, ClusterableMode
|
|
|
351
344
|
return self.first_name + " " + self.last_name
|
|
352
345
|
|
|
353
346
|
panels = [
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
347
|
+
"first_name",
|
|
348
|
+
"last_name",
|
|
349
|
+
"image",
|
|
357
350
|
MultiFieldPanel(LinkFields.panels, "Link"),
|
|
358
351
|
InlinePanel("awards", label="Awards"),
|
|
359
352
|
]
|
|
@@ -422,24 +415,24 @@ class EventPage(Page):
|
|
|
422
415
|
|
|
423
416
|
content_panels = [
|
|
424
417
|
FieldPanel("title", classname="title"),
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
418
|
+
"date_from",
|
|
419
|
+
"date_to",
|
|
420
|
+
"time_from",
|
|
421
|
+
"time_to",
|
|
422
|
+
"location",
|
|
430
423
|
FieldPanel("audience", help_text="Who this event is for"),
|
|
431
|
-
|
|
432
|
-
|
|
424
|
+
"cost",
|
|
425
|
+
"signup_link",
|
|
433
426
|
InlinePanel("carousel_items", label="Carousel items"),
|
|
434
|
-
|
|
427
|
+
"body",
|
|
435
428
|
InlinePanel(
|
|
436
429
|
"speakers",
|
|
437
|
-
label="
|
|
430
|
+
label="Speaker",
|
|
438
431
|
heading="Speaker lineup",
|
|
439
432
|
help_text="Put the keynote speaker first",
|
|
440
433
|
),
|
|
441
434
|
InlinePanel("related_links", label="Related links"),
|
|
442
|
-
|
|
435
|
+
"categories",
|
|
443
436
|
# InlinePanel related model uses `pk` not `id`
|
|
444
437
|
InlinePanel("head_counts", label="Head Counts"),
|
|
445
438
|
]
|
|
@@ -527,6 +520,9 @@ class EventIndex(Page):
|
|
|
527
520
|
intro = RichTextField(blank=True, max_length=50)
|
|
528
521
|
ajax_template = "tests/includes/event_listing.html"
|
|
529
522
|
|
|
523
|
+
# NOTE: Using a mix of enum and string values to test handling of both
|
|
524
|
+
allowed_http_methods = [HTTPMethod.GET, "OPTIONS"]
|
|
525
|
+
|
|
530
526
|
def get_events(self):
|
|
531
527
|
return self.get_children().live().type(EventPage)
|
|
532
528
|
|
|
@@ -715,18 +711,37 @@ class FormPageWithRedirect(AbstractEmailForm):
|
|
|
715
711
|
# FormPage with a custom FormSubmission
|
|
716
712
|
|
|
717
713
|
|
|
714
|
+
class FormPageWithCustomSubmissionForm(WagtailAdminFormPageForm):
|
|
715
|
+
"""
|
|
716
|
+
Used to validate that admin forms can validate the page's submissions via
|
|
717
|
+
extending the form class.
|
|
718
|
+
"""
|
|
719
|
+
|
|
720
|
+
def clean(self):
|
|
721
|
+
cleaned_data = super().clean()
|
|
722
|
+
from_address = cleaned_data.get("from_address")
|
|
723
|
+
if from_address and "example.com" in from_address:
|
|
724
|
+
raise ValidationError("Email cannot be from example.com")
|
|
725
|
+
|
|
726
|
+
return cleaned_data
|
|
727
|
+
|
|
728
|
+
|
|
718
729
|
class FormPageWithCustomSubmission(AbstractEmailForm):
|
|
719
730
|
"""
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
731
|
+
A ``FormPage`` with a custom FormSubmission and other extensive customizations:
|
|
732
|
+
|
|
733
|
+
* A custom submission model
|
|
734
|
+
* A custom related_name (see `FormFieldWithCustomSubmission.page`)
|
|
735
|
+
* Saves reference to a user
|
|
736
|
+
* Doesn't render html form, if submission for current user is present
|
|
737
|
+
* A custom clean method that does not allow the ``from_address`` to be set to anything including example.com
|
|
725
738
|
"""
|
|
726
739
|
|
|
727
740
|
intro = RichTextField(blank=True)
|
|
728
741
|
thank_you_text = RichTextField(blank=True)
|
|
729
742
|
|
|
743
|
+
base_form_class = FormPageWithCustomSubmissionForm
|
|
744
|
+
|
|
730
745
|
def get_context(self, request, *args, **kwargs):
|
|
731
746
|
context = super().get_context(request)
|
|
732
747
|
context["greeting"] = "hello world"
|
|
@@ -1816,12 +1831,12 @@ class ImportantPagesGenericSetting(BaseGenericSetting):
|
|
|
1816
1831
|
verbose_name_plural = _("Important pages settings")
|
|
1817
1832
|
|
|
1818
1833
|
|
|
1819
|
-
@register_setting(icon="
|
|
1834
|
+
@register_setting(icon="tag")
|
|
1820
1835
|
class IconSiteSetting(BaseSiteSetting):
|
|
1821
1836
|
pass
|
|
1822
1837
|
|
|
1823
1838
|
|
|
1824
|
-
@register_setting(icon="
|
|
1839
|
+
@register_setting(icon="tag")
|
|
1825
1840
|
class IconGenericSetting(BaseGenericSetting):
|
|
1826
1841
|
pass
|
|
1827
1842
|
|
|
@@ -2149,13 +2164,13 @@ class PersonPage(Page):
|
|
|
2149
2164
|
content_panels = Page.content_panels + [
|
|
2150
2165
|
MultiFieldPanel(
|
|
2151
2166
|
[
|
|
2152
|
-
|
|
2153
|
-
|
|
2167
|
+
"first_name",
|
|
2168
|
+
"last_name",
|
|
2154
2169
|
],
|
|
2155
2170
|
"Person",
|
|
2156
2171
|
),
|
|
2157
|
-
|
|
2158
|
-
|
|
2172
|
+
"addresses",
|
|
2173
|
+
"social_links",
|
|
2159
2174
|
]
|
|
2160
2175
|
|
|
2161
2176
|
class Meta:
|
|
@@ -2205,10 +2220,7 @@ class SocialLink(index.Indexed, ClusterableModel):
|
|
|
2205
2220
|
to="tests.PersonPage", related_name="social_links", verbose_name="Person"
|
|
2206
2221
|
)
|
|
2207
2222
|
|
|
2208
|
-
panels = [
|
|
2209
|
-
FieldPanel("url"),
|
|
2210
|
-
FieldPanel("kind"),
|
|
2211
|
-
]
|
|
2223
|
+
panels = ["url", "kind"]
|
|
2212
2224
|
|
|
2213
2225
|
class Meta:
|
|
2214
2226
|
verbose_name = "Social link"
|
|
@@ -2340,7 +2352,9 @@ class ModelWithNullableParentalKey(models.Model):
|
|
|
2340
2352
|
|
|
2341
2353
|
class GalleryPage(Page):
|
|
2342
2354
|
content_panels = Page.content_panels + [
|
|
2343
|
-
MultipleChooserPanel(
|
|
2355
|
+
MultipleChooserPanel(
|
|
2356
|
+
"gallery_images", heading="Gallery images", chooser_field_name="image"
|
|
2357
|
+
)
|
|
2344
2358
|
]
|
|
2345
2359
|
|
|
2346
2360
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{% extends "wagtailcore/shared/block_preview.html" %}
|
|
2
|
+
{% load static %}
|
|
3
|
+
|
|
4
|
+
{% block content %}
|
|
5
|
+
<div class="my-preview-wrapper">
|
|
6
|
+
{{ block.super }}
|
|
7
|
+
</div>
|
|
8
|
+
{% endblock %}
|
|
9
|
+
|
|
10
|
+
{% block css %}
|
|
11
|
+
<link rel="stylesheet" href="{% static 'css/custom.css' %}">
|
|
12
|
+
{% endblock %}
|
|
13
|
+
|
|
14
|
+
{% block js %}
|
|
15
|
+
<script type="module" src="{% static 'js/custom.js' %}"></script>
|
|
16
|
+
{% endblock %}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
1
3
|
from django import forms
|
|
2
4
|
from django.http import HttpResponse
|
|
3
5
|
from django.utils.safestring import mark_safe
|
|
@@ -432,3 +434,10 @@ def register_animated_advert_chooser_viewset():
|
|
|
432
434
|
@hooks.register("register_admin_viewset")
|
|
433
435
|
def register_event_page_listing_viewset():
|
|
434
436
|
return event_page_listing_viewset
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
@hooks.register("get_avatar_url")
|
|
440
|
+
def register_avatar_intercept_url(user, size):
|
|
441
|
+
if os.environ.get("AVATAR_INTERCEPT"):
|
|
442
|
+
return "/some/avatar/fred.png"
|
|
443
|
+
return None
|