wagtail 6.4rc1__py3-none-any.whl → 7.0__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 +4 -4
- wagtail/admin/action_menu.py +3 -0
- wagtail/admin/active_filters.py +218 -0
- wagtail/admin/auth.py +3 -39
- wagtail/admin/filters.py +9 -2
- wagtail/admin/forms/choosers.py +8 -7
- wagtail/admin/forms/models.py +46 -1
- wagtail/admin/forms/pages.py +9 -0
- wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/django.po +31 -34
- wagtail/admin/locale/ar/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/djangojs.po +9 -1
- wagtail/admin/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/admin/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/be/LC_MESSAGES/django.po +28 -29
- wagtail/admin/locale/be/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/be/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/bg/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/bg/LC_MESSAGES/django.po +3 -7
- wagtail/admin/locale/bg/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/bg/LC_MESSAGES/djangojs.po +5 -2
- wagtail/admin/locale/bn/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/bn/LC_MESSAGES/django.po +1 -7
- wagtail/admin/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ca/LC_MESSAGES/django.po +131 -122
- wagtail/admin/locale/ca/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ca/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/cs/LC_MESSAGES/django.po +33 -46
- wagtail/admin/locale/cs/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/cs/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/cy/LC_MESSAGES/django.po +1 -7
- wagtail/admin/locale/cy/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/cy/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/da/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/da/LC_MESSAGES/django.po +4 -21
- wagtail/admin/locale/da/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/da/LC_MESSAGES/djangojs.po +5 -2
- wagtail/admin/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/de/LC_MESSAGES/django.po +134 -126
- wagtail/admin/locale/de/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/de/LC_MESSAGES/djangojs.po +9 -2
- wagtail/admin/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/dv/LC_MESSAGES/django.po +13 -61
- wagtail/admin/locale/dv/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/dv/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/el/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/el/LC_MESSAGES/django.po +9 -71
- wagtail/admin/locale/el/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/el/LC_MESSAGES/djangojs.po +9 -2
- wagtail/admin/locale/en/LC_MESSAGES/django.po +386 -319
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +11 -7
- wagtail/admin/locale/en_IN/LC_MESSAGES/djangojs.po +2 -2
- wagtail/admin/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/es/LC_MESSAGES/django.po +37 -147
- wagtail/admin/locale/es/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/es/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/es_419/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/es_419/LC_MESSAGES/django.po +2 -7
- wagtail/admin/locale/es_VE/LC_MESSAGES/django.po +2 -1
- wagtail/admin/locale/es_VE/LC_MESSAGES/djangojs.po +2 -2
- wagtail/admin/locale/et/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/et/LC_MESSAGES/django.po +31 -38
- wagtail/admin/locale/et/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/et/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/admin/locale/eu/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/eu/LC_MESSAGES/djangojs.po +5 -2
- wagtail/admin/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/fa/LC_MESSAGES/django.po +11 -112
- wagtail/admin/locale/fa/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/fa/LC_MESSAGES/djangojs.po +9 -2
- wagtail/admin/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/fi/LC_MESSAGES/django.po +34 -63
- wagtail/admin/locale/fi/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/fi/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/fr/LC_MESSAGES/django.po +139 -134
- wagtail/admin/locale/fr/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/fr/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/gl/LC_MESSAGES/django.po +130 -121
- wagtail/admin/locale/gl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/gl/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.po +5 -9
- wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.po +7 -4
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.po +31 -38
- wagtail/admin/locale/hr_HR/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/hr_HR/LC_MESSAGES/djangojs.po +10 -4
- wagtail/admin/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/admin/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hu/LC_MESSAGES/django.po +340 -115
- wagtail/admin/locale/hu/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/hu/LC_MESSAGES/djangojs.po +13 -2
- wagtail/admin/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/id_ID/LC_MESSAGES/django.po +12 -27
- wagtail/admin/locale/id_ID/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/id_ID/LC_MESSAGES/djangojs.po +5 -1
- wagtail/admin/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/is_IS/LC_MESSAGES/django.po +35 -144
- wagtail/admin/locale/is_IS/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/is_IS/LC_MESSAGES/djangojs.po +11 -5
- wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/django.po +38 -164
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ja/LC_MESSAGES/django.po +15 -40
- wagtail/admin/locale/ja/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ja/LC_MESSAGES/djangojs.po +9 -2
- wagtail/admin/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/admin/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ko/LC_MESSAGES/django.po +96 -114
- wagtail/admin/locale/ko/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ko/LC_MESSAGES/djangojs.po +21 -2
- wagtail/admin/locale/lt/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/lt/LC_MESSAGES/django.po +31 -40
- wagtail/admin/locale/lt/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/lt/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/lv/LC_MESSAGES/django.po +10 -13
- wagtail/admin/locale/lv/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/lv/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/admin/locale/mi/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/mi/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/mn/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/mn/LC_MESSAGES/django.po +14 -24
- wagtail/admin/locale/mn/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/mn/LC_MESSAGES/djangojs.po +5 -2
- wagtail/admin/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/admin/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/nb/LC_MESSAGES/django.po +32 -37
- wagtail/admin/locale/nb/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/nb/LC_MESSAGES/djangojs.po +11 -4
- wagtail/admin/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/nl/LC_MESSAGES/django.po +102 -132
- wagtail/admin/locale/nl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/nl/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pl/LC_MESSAGES/django.po +38 -106
- wagtail/admin/locale/pl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/pl/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pt_BR/LC_MESSAGES/django.po +38 -151
- wagtail/admin/locale/pt_BR/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/pt_BR/LC_MESSAGES/djangojs.po +10 -4
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +32 -137
- wagtail/admin/locale/pt_PT/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/pt_PT/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ro/LC_MESSAGES/django.po +35 -161
- wagtail/admin/locale/ro/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ro/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ru/LC_MESSAGES/django.po +100 -157
- wagtail/admin/locale/ru/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ru/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sk_SK/LC_MESSAGES/django.po +6 -17
- wagtail/admin/locale/sk_SK/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/sk_SK/LC_MESSAGES/djangojs.po +10 -4
- wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/django.po +36 -77
- wagtail/admin/locale/sl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sv/LC_MESSAGES/django.po +35 -129
- wagtail/admin/locale/sv/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/sv/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/tet/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/tet/LC_MESSAGES/django.po +6 -21
- wagtail/admin/locale/tet/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/tet/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/th/LC_MESSAGES/django.po +11 -33
- wagtail/admin/locale/th/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/th/LC_MESSAGES/djangojs.po +5 -2
- wagtail/admin/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/tr/LC_MESSAGES/django.po +29 -29
- wagtail/admin/locale/tr/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/tr/LC_MESSAGES/djangojs.po +9 -3
- wagtail/admin/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/tr_TR/LC_MESSAGES/django.po +29 -29
- wagtail/admin/locale/tr_TR/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/tr_TR/LC_MESSAGES/djangojs.po +11 -4
- wagtail/admin/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ug/LC_MESSAGES/django.po +17 -134
- wagtail/admin/locale/ug/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ug/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/uk/LC_MESSAGES/django.po +31 -161
- wagtail/admin/locale/uk/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/uk/LC_MESSAGES/djangojs.po +10 -4
- wagtail/admin/locale/vi/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/vi/LC_MESSAGES/django.po +2 -8
- wagtail/admin/locale/vi/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/vi/LC_MESSAGES/djangojs.po +5 -2
- wagtail/admin/locale/zh/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/zh/LC_MESSAGES/django.po +2 -6
- wagtail/admin/locale/zh/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/zh/LC_MESSAGES/djangojs.po +5 -2
- wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.po +38 -112
- wagtail/admin/locale/zh_Hans/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/zh_Hans/LC_MESSAGES/djangojs.po +11 -5
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.po +12 -33
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/djangojs.po +10 -4
- wagtail/admin/localization.py +42 -1
- wagtail/admin/menu.py +1 -10
- wagtail/admin/paginator.py +95 -0
- wagtail/admin/panels/field_panel.py +27 -6
- wagtail/admin/panels/inline_panel.py +28 -11
- wagtail/admin/panels/multiple_chooser_panel.py +3 -3
- wagtail/admin/rich_text/converters/html_to_contentstate.py +6 -6
- wagtail/admin/search.py +1 -10
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
- wagtail/admin/static/wagtailadmin/js/bulk-actions.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/draftail.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/telepath/widgets.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +32 -11
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/templates/wagtailadmin/admin_base.html +1 -0
- wagtail/admin/templates/wagtailadmin/generic/index.html +7 -2
- wagtail/admin/templates/wagtailadmin/home/upgrade_notification.html +1 -0
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +2 -3
- wagtail/admin/templates/wagtailadmin/pages/action_menu/publish.html +2 -2
- wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_move.html +0 -1
- wagtail/admin/templates/wagtailadmin/pages/move_choose_destination.html +0 -1
- wagtail/admin/templates/wagtailadmin/panels/publishing/schedule_publishing_panel.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/active_filters.html +8 -1
- wagtail/admin/templates/wagtailadmin/shared/pagination_nav.html +25 -13
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/privacy.html +1 -2
- wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/workflow.html +1 -1
- wagtail/admin/templates/wagtailadmin/skeleton.html +2 -1
- wagtail/admin/templates/wagtailadmin/tables/locale_cell.html +4 -0
- wagtail/admin/templates/wagtailadmin/userbar/base.html +10 -8
- wagtail/admin/templatetags/wagtailadmin_tags.py +57 -132
- wagtail/admin/tests/pages/test_bulk_actions/test_bulk_move.py +31 -0
- wagtail/admin/tests/pages/test_create_page.py +627 -0
- wagtail/admin/tests/pages/test_edit_page.py +102 -18
- wagtail/admin/tests/pages/test_explorer_view.py +55 -26
- wagtail/admin/tests/pages/test_page_search.py +10 -0
- wagtail/admin/tests/pages/test_page_usage.py +2 -1
- wagtail/admin/tests/pages/test_preview.py +176 -36
- wagtail/admin/tests/pages/test_revisions.py +4 -7
- wagtail/admin/tests/test_account_management.py +1 -1
- wagtail/admin/tests/test_admin_search.py +1 -0
- wagtail/admin/tests/test_block_preview.py +4 -0
- wagtail/admin/tests/test_buttons_hooks.py +9 -145
- wagtail/admin/tests/test_collections_views.py +60 -0
- wagtail/admin/tests/test_contentstate.py +1 -1
- wagtail/admin/tests/test_dashboard.py +25 -0
- wagtail/admin/tests/test_edit_handlers.py +64 -0
- wagtail/admin/tests/test_forms.py +38 -0
- wagtail/admin/tests/test_keyboard_shortcuts.py +141 -5
- wagtail/admin/tests/test_page_chooser.py +2 -2
- wagtail/admin/tests/test_paginator.py +86 -0
- wagtail/admin/tests/test_privacy.py +12 -1
- wagtail/admin/tests/test_reports_views.py +8 -43
- wagtail/admin/tests/test_rich_text.py +14 -0
- wagtail/admin/tests/test_templatetags.py +50 -36
- wagtail/admin/tests/test_upgrade_notification.py +3 -0
- wagtail/admin/tests/test_userbar.py +79 -15
- wagtail/admin/tests/test_views.py +16 -1
- wagtail/admin/tests/test_widgets.py +47 -8
- wagtail/admin/tests/test_workflows.py +119 -6
- wagtail/admin/tests/tests.py +16 -15
- wagtail/admin/tests/ui/test_sidebar.py +0 -27
- wagtail/admin/tests/viewsets/test_chooser_viewset.py +38 -4
- wagtail/admin/tests/viewsets/test_model_viewset.py +1 -37
- wagtail/admin/ui/side_panels.py +14 -16
- wagtail/admin/ui/sidebar.py +5 -37
- wagtail/admin/ui/tables/__init__.py +34 -2
- wagtail/admin/ui/tables/pages.py +9 -0
- wagtail/admin/urls/__init__.py +2 -2
- wagtail/admin/urls/pages.py +3 -1
- wagtail/admin/userbar.py +3 -5
- wagtail/admin/utils.py +43 -4
- wagtail/admin/views/generic/base.py +16 -115
- wagtail/admin/views/generic/chooser.py +25 -8
- wagtail/admin/views/generic/mixins.py +45 -11
- wagtail/admin/views/generic/models.py +15 -30
- wagtail/admin/views/generic/preview.py +11 -3
- wagtail/admin/views/generic/workflow.py +11 -1
- wagtail/admin/views/i18n.py +14 -0
- wagtail/admin/views/pages/bulk_actions/move.py +1 -1
- wagtail/admin/views/pages/create.py +68 -6
- wagtail/admin/views/pages/edit.py +33 -14
- wagtail/admin/views/pages/listing.py +3 -2
- wagtail/admin/views/pages/move.py +43 -29
- wagtail/admin/views/pages/preview.py +15 -2
- wagtail/admin/views/pages/search.py +3 -0
- wagtail/admin/views/reports/base.py +0 -22
- wagtail/admin/views/reports/page_types_usage.py +2 -1
- wagtail/admin/views/tags.py +3 -1
- wagtail/admin/views/workflows.py +0 -3
- wagtail/admin/viewsets/model.py +5 -48
- wagtail/admin/wagtail_hooks.py +16 -17
- wagtail/admin/widgets/button.py +3 -33
- wagtail/admin/widgets/tags.py +31 -3
- wagtail/api/v2/views.py +4 -4
- wagtail/blocks/base.py +78 -34
- wagtail/blocks/field_block.py +2 -1
- wagtail/blocks/list_block.py +2 -1
- wagtail/blocks/migrations/operations.py +10 -10
- wagtail/blocks/stream_block.py +19 -11
- wagtail/blocks/struct_block.py +4 -0
- wagtail/compat.py +17 -1
- wagtail/contrib/forms/forms.py +64 -31
- wagtail/contrib/forms/locale/af/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ar/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/be/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ca/LC_MESSAGES/django.po +15 -6
- wagtail/contrib/forms/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/cs/LC_MESSAGES/django.po +2 -9
- wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.po +2 -7
- wagtail/contrib/forms/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/de/LC_MESSAGES/django.po +3 -10
- wagtail/contrib/forms/locale/dv/LC_MESSAGES/django.po +2 -1
- wagtail/contrib/forms/locale/el/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/el/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +13 -6
- wagtail/contrib/forms/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/es/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/et/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/et/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/fa/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/fi/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/fr/LC_MESSAGES/django.po +8 -6
- wagtail/contrib/forms/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/gl/LC_MESSAGES/django.po +17 -6
- wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/hr_HR/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/hu/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/hy/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/id_ID/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/is_IS/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/it/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ja/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ko/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/lt/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/lt/LC_MESSAGES/django.po +1 -8
- wagtail/contrib/forms/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/mn/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/mn/LC_MESSAGES/django.po +3 -2
- wagtail/contrib/forms/locale/my/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/my/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/nb/LC_MESSAGES/django.po +1 -8
- wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.po +2 -10
- wagtail/contrib/forms/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/pl/LC_MESSAGES/django.po +2 -8
- wagtail/contrib/forms/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/pt_BR/LC_MESSAGES/django.po +2 -8
- wagtail/contrib/forms/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/pt_PT/LC_MESSAGES/django.po +1 -8
- wagtail/contrib/forms/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ro/LC_MESSAGES/django.po +2 -8
- wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.po +2 -7
- wagtail/contrib/forms/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/sk_SK/LC_MESSAGES/django.po +1 -8
- wagtail/contrib/forms/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/sl/LC_MESSAGES/django.po +2 -8
- wagtail/contrib/forms/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/sv/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/tet/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/tet/LC_MESSAGES/django.po +1 -9
- wagtail/contrib/forms/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/th/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/tr/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/tr_TR/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ug/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/uk/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/zh_Hans/LC_MESSAGES/django.po +2 -8
- wagtail/contrib/forms/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/zh_Hant/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/forms/tests/test_forms.py +62 -0
- wagtail/contrib/forms/tests/test_views.py +161 -5
- wagtail/contrib/frontend_cache/backends/cloudfront.py +1 -29
- wagtail/contrib/frontend_cache/tests.py +112 -52
- wagtail/contrib/frontend_cache/utils.py +109 -17
- wagtail/contrib/redirects/forms.py +3 -2
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/be/LC_MESSAGES/django.po +1 -10
- wagtail/contrib/redirects/locale/bg/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/bg/LC_MESSAGES/django.po +4 -13
- wagtail/contrib/redirects/locale/bn/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/bn/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +8 -17
- wagtail/contrib/redirects/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/cs/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.po +8 -16
- wagtail/contrib/redirects/locale/da/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/da/LC_MESSAGES/django.po +1 -10
- wagtail/contrib/redirects/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/de/LC_MESSAGES/django.po +8 -16
- wagtail/contrib/redirects/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/dv/LC_MESSAGES/django.po +2 -10
- wagtail/contrib/redirects/locale/el/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/el/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +8 -8
- wagtail/contrib/redirects/locale/en_IN/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/es/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/es_419/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/es_419/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/redirects/locale/es_VE/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/et/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/et/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/eu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/eu/LC_MESSAGES/django.po +1 -4
- wagtail/contrib/redirects/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/fa/LC_MESSAGES/django.po +9 -17
- wagtail/contrib/redirects/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/fi/LC_MESSAGES/django.po +8 -17
- wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.po +9 -16
- wagtail/contrib/redirects/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/gl/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/hi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/hr_HR/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/ht/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ht/LC_MESSAGES/django.po +1 -4
- wagtail/contrib/redirects/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/hu/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/hy/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/id_ID/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/is_IS/LC_MESSAGES/django.po +8 -17
- wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ja/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/ka/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ka/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/redirects/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ko/LC_MESSAGES/django.po +23 -16
- wagtail/contrib/redirects/locale/lt/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/lt/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/lv/LC_MESSAGES/django.po +4 -13
- wagtail/contrib/redirects/locale/mi/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/mi/LC_MESSAGES/django.po +4 -13
- wagtail/contrib/redirects/locale/mn/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/mn/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/my/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/my/LC_MESSAGES/django.po +3 -12
- wagtail/contrib/redirects/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/nb/LC_MESSAGES/django.po +8 -16
- wagtail/contrib/redirects/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/nl/LC_MESSAGES/django.po +8 -17
- wagtail/contrib/redirects/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/pl/LC_MESSAGES/django.po +8 -17
- wagtail/contrib/redirects/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/pt_BR/LC_MESSAGES/django.po +9 -17
- wagtail/contrib/redirects/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/pt_PT/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ro/LC_MESSAGES/django.po +9 -17
- wagtail/contrib/redirects/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ru/LC_MESSAGES/django.po +9 -17
- wagtail/contrib/redirects/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/sk_SK/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/sl/LC_MESSAGES/django.po +8 -17
- wagtail/contrib/redirects/locale/sr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.po +8 -17
- wagtail/contrib/redirects/locale/ta/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/tet/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/tet/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/th/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/tr/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/tr_TR/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ug/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/uk/LC_MESSAGES/django.po +9 -17
- wagtail/contrib/redirects/locale/vi/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/vi/LC_MESSAGES/django.po +1 -10
- wagtail/contrib/redirects/locale/zh/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/zh/LC_MESSAGES/django.po +4 -13
- wagtail/contrib/redirects/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/zh_Hans/LC_MESSAGES/django.po +8 -17
- wagtail/contrib/redirects/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/zh_Hant/LC_MESSAGES/django.po +7 -16
- wagtail/contrib/redirects/tmp_storages.py +1 -0
- wagtail/contrib/routable_page/tests.py +3 -3
- wagtail/contrib/search_promotions/forms.py +3 -2
- wagtail/contrib/search_promotions/locale/af/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/af/LC_MESSAGES/django.po +4 -1
- wagtail/contrib/search_promotions/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ar/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/az_AZ/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/az_AZ/LC_MESSAGES/django.po +1 -4
- wagtail/contrib/search_promotions/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/be/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/bg/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/bg/LC_MESSAGES/django.po +9 -22
- wagtail/contrib/search_promotions/locale/bn/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/bn/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ca/LC_MESSAGES/django.po +27 -37
- wagtail/contrib/search_promotions/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/cs/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.po +18 -37
- wagtail/contrib/search_promotions/locale/da/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/da/LC_MESSAGES/django.po +9 -12
- wagtail/contrib/search_promotions/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/de/LC_MESSAGES/django.po +27 -37
- wagtail/contrib/search_promotions/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/dv/LC_MESSAGES/django.po +10 -12
- wagtail/contrib/search_promotions/locale/el/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/el/LC_MESSAGES/django.po +14 -30
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +19 -23
- wagtail/contrib/search_promotions/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/es/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/es_419/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/es_419/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/et/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/et/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/eu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/eu/LC_MESSAGES/django.po +7 -4
- wagtail/contrib/search_promotions/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/fa/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/fi/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.po +28 -38
- wagtail/contrib/search_promotions/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/gl/LC_MESSAGES/django.po +29 -39
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.po +12 -19
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.po +21 -37
- wagtail/contrib/search_promotions/locale/ht/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ht/LC_MESSAGES/django.po +3 -9
- wagtail/contrib/search_promotions/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/hu/LC_MESSAGES/django.po +31 -38
- wagtail/contrib/search_promotions/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/id_ID/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/is_IS/LC_MESSAGES/django.po +20 -36
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +18 -34
- wagtail/contrib/search_promotions/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ja/LC_MESSAGES/django.po +14 -30
- wagtail/contrib/search_promotions/locale/ka/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ka/LC_MESSAGES/django.po +3 -6
- wagtail/contrib/search_promotions/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ko/LC_MESSAGES/django.po +18 -30
- wagtail/contrib/search_promotions/locale/lt/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/lt/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/lv/LC_MESSAGES/django.po +9 -22
- wagtail/contrib/search_promotions/locale/mi/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/mi/LC_MESSAGES/django.po +6 -25
- wagtail/contrib/search_promotions/locale/mn/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/mn/LC_MESSAGES/django.po +9 -22
- wagtail/contrib/search_promotions/locale/my/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/my/LC_MESSAGES/django.po +3 -12
- wagtail/contrib/search_promotions/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/nb/LC_MESSAGES/django.po +14 -30
- wagtail/contrib/search_promotions/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/nl/LC_MESSAGES/django.po +27 -37
- wagtail/contrib/search_promotions/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/pl/LC_MESSAGES/django.po +17 -33
- wagtail/contrib/search_promotions/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/pt_BR/LC_MESSAGES/django.po +18 -34
- wagtail/contrib/search_promotions/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/pt_PT/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ro/LC_MESSAGES/django.po +21 -37
- wagtail/contrib/search_promotions/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ru/LC_MESSAGES/django.po +29 -39
- wagtail/contrib/search_promotions/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/sk_SK/LC_MESSAGES/django.po +12 -31
- wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.po +21 -37
- wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/tet/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/tet/LC_MESSAGES/django.po +15 -28
- wagtail/contrib/search_promotions/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/th/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/tr_TR/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ug/LC_MESSAGES/django.po +17 -36
- wagtail/contrib/search_promotions/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/uk/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/vi/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/vi/LC_MESSAGES/django.po +3 -12
- wagtail/contrib/search_promotions/locale/zh/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/zh/LC_MESSAGES/django.po +9 -22
- wagtail/contrib/search_promotions/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/zh_Hans/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/zh_Hant/LC_MESSAGES/django.po +15 -31
- wagtail/contrib/search_promotions/models.py +1 -7
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/queries/chooser/results.html +1 -1
- wagtail/contrib/search_promotions/tests.py +4 -5
- wagtail/contrib/search_promotions/views/settings.py +1 -2
- wagtail/contrib/settings/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/en_IN/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/es_VE/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/hi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/sr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/ta/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/registry.py +1 -11
- wagtail/contrib/simple_translation/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/hr_HR/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/simple_translation/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/simple_translation/locale/hu/LC_MESSAGES/django.po +6 -3
- wagtail/contrib/simple_translation/locale/is_IS/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/simple_translation/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/nb/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/simple_translation/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/pt_BR/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/simple_translation/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/locale/zh_Hans/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/simple_translation/locale/zh_Hant/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/styleguide/locale/af/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/styleguide/locale/be/LC_MESSAGES/django.po +3 -2
- wagtail/contrib/styleguide/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/cy/LC_MESSAGES/django.po +2 -1
- wagtail/contrib/styleguide/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/dv/LC_MESSAGES/django.po +2 -1
- wagtail/contrib/styleguide/locale/el/LC_MESSAGES/django.po +2 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
- wagtail/contrib/styleguide/locale/en_IN/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/es_VE/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/hi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/styleguide/locale/sk_SK/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/styleguide/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ta/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/views.py +2 -1
- wagtail/contrib/table_block/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/en_IN/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/blocks.py +5 -0
- wagtail/contrib/typed_table_block/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/contrib/typed_table_block/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/is_IS/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/typed_table_block/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/pt_BR/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/typed_table_block/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/zh_Hans/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/typed_table_block/locale/zh_Hant/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/typed_table_block/tests.py +27 -0
- wagtail/coreutils.py +0 -19
- wagtail/documents/locale/af/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ar/LC_MESSAGES/django.po +3 -2
- wagtail/documents/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ca/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/de/LC_MESSAGES/django.po +3 -3
- wagtail/documents/locale/dv/LC_MESSAGES/django.po +2 -1
- wagtail/documents/locale/el/LC_MESSAGES/django.po +2 -1
- wagtail/documents/locale/en/LC_MESSAGES/django.po +4 -4
- wagtail/documents/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/es/LC_MESSAGES/django.po +3 -2
- wagtail/documents/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/fi/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/fr/LC_MESSAGES/django.po +2 -1
- wagtail/documents/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/hu/LC_MESSAGES/django.po +18 -3
- wagtail/documents/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/it/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ko/LC_MESSAGES/django.po +14 -2
- wagtail/documents/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/nb/LC_MESSAGES/django.po +3 -2
- wagtail/documents/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/nl/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/pl/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/pt_BR/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ro/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ru/LC_MESSAGES/django.po +5 -2
- wagtail/documents/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/sk_SK/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/sl/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/zh_Hans/LC_MESSAGES/django.po +3 -2
- wagtail/documents/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/documents/rich_text/contentstate.py +1 -0
- wagtail/documents/rich_text/editor_html.py +1 -0
- wagtail/documents/tests/test_collection_privacy.py +1 -1
- wagtail/documents/tests/test_serializers.py +0 -1
- wagtail/documents/views/serve.py +0 -15
- wagtail/documents/wagtail_hooks.py +2 -17
- wagtail/embeds/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/rich_text/contentstate.py +1 -0
- wagtail/embeds/rich_text/editor_html.py +1 -0
- wagtail/embeds/wagtail_hooks.py +1 -1
- wagtail/images/formats.py +0 -11
- wagtail/images/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ca/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/cs/LC_MESSAGES/django.po +3 -2
- wagtail/images/locale/cy/LC_MESSAGES/django.po +2 -1
- wagtail/images/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/de/LC_MESSAGES/django.po +3 -2
- wagtail/images/locale/dv/LC_MESSAGES/django.po +2 -1
- wagtail/images/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/en/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/fa/LC_MESSAGES/django.po +3 -2
- wagtail/images/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/fi/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/fr/LC_MESSAGES/django.po +3 -2
- wagtail/images/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/gl/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/hu/LC_MESSAGES/django.po +23 -3
- wagtail/images/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/it/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ko/LC_MESSAGES/django.po +31 -2
- wagtail/images/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/mn/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/mn/LC_MESSAGES/django.po +3 -2
- wagtail/images/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/nb/LC_MESSAGES/django.po +3 -2
- wagtail/images/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/nl/LC_MESSAGES/django.po +4 -5
- wagtail/images/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/pl/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/pt_BR/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ro/LC_MESSAGES/django.po +3 -2
- wagtail/images/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ru/LC_MESSAGES/django.po +5 -2
- wagtail/images/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/sk_SK/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/sl/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/sv/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/uk/LC_MESSAGES/django.po +5 -4
- wagtail/images/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/zh_Hans/LC_MESSAGES/django.po +2 -1
- wagtail/images/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/images/management/commands/wagtail_update_image_renditions.py +1 -1
- wagtail/images/models.py +23 -7
- wagtail/images/signal_handlers.py +1 -1
- wagtail/images/tests/test_admin_views.py +1 -1
- wagtail/images/tests/test_models.py +39 -3
- wagtail/images/tests/tests.py +0 -6
- wagtail/images/wagtail_hooks.py +2 -2
- wagtail/locale/af/LC_MESSAGES/django.po +1 -1
- wagtail/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ar/LC_MESSAGES/django.po +59 -50
- wagtail/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/be/LC_MESSAGES/django.po +55 -51
- wagtail/locale/bg/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/bg/LC_MESSAGES/django.po +7 -4
- wagtail/locale/bn/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/bn/LC_MESSAGES/django.po +7 -1
- wagtail/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ca/LC_MESSAGES/django.po +243 -234
- wagtail/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/cs/LC_MESSAGES/django.po +181 -172
- wagtail/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/cy/LC_MESSAGES/django.po +18 -12
- wagtail/locale/da/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/da/LC_MESSAGES/django.po +16 -7
- wagtail/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/de/LC_MESSAGES/django.po +248 -238
- wagtail/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/dv/LC_MESSAGES/django.po +225 -215
- wagtail/locale/el/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/el/LC_MESSAGES/django.po +85 -75
- wagtail/locale/en/LC_MESSAGES/django.po +339 -339
- wagtail/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/es/LC_MESSAGES/django.po +201 -192
- wagtail/locale/es_419/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/es_419/LC_MESSAGES/django.po +7 -1
- wagtail/locale/et/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/et/LC_MESSAGES/django.po +176 -173
- wagtail/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/fa/LC_MESSAGES/django.po +59 -50
- wagtail/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/fi/LC_MESSAGES/django.po +198 -189
- wagtail/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/fr/LC_MESSAGES/django.po +245 -235
- wagtail/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/gl/LC_MESSAGES/django.po +244 -235
- wagtail/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/he_IL/LC_MESSAGES/django.po +12 -9
- wagtail/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/hr_HR/LC_MESSAGES/django.po +187 -184
- wagtail/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/hu/LC_MESSAGES/django.po +260 -229
- wagtail/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/id_ID/LC_MESSAGES/django.po +52 -49
- wagtail/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/is_IS/LC_MESSAGES/django.po +241 -232
- wagtail/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/it/LC_MESSAGES/django.po +233 -224
- wagtail/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ja/LC_MESSAGES/django.po +119 -110
- wagtail/locale/ka/LC_MESSAGES/django.po +4 -4
- wagtail/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ko/LC_MESSAGES/django.po +95 -51
- wagtail/locale/lt/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/lt/LC_MESSAGES/django.po +62 -53
- wagtail/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/lv/LC_MESSAGES/django.po +25 -22
- wagtail/locale/mi/LC_MESSAGES/django.po +167 -167
- wagtail/locale/mn/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/mn/LC_MESSAGES/django.po +54 -50
- wagtail/locale/my/LC_MESSAGES/django.po +6 -6
- wagtail/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/nb/LC_MESSAGES/django.po +59 -50
- wagtail/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/nl/LC_MESSAGES/django.po +242 -233
- wagtail/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/pl/LC_MESSAGES/django.po +241 -232
- wagtail/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/pt_BR/LC_MESSAGES/django.po +211 -202
- wagtail/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/pt_PT/LC_MESSAGES/django.po +191 -180
- wagtail/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ro/LC_MESSAGES/django.po +242 -232
- wagtail/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ru/LC_MESSAGES/django.po +246 -234
- wagtail/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sk_SK/LC_MESSAGES/django.po +50 -47
- wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sl/LC_MESSAGES/django.po +242 -233
- wagtail/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sv/LC_MESSAGES/django.po +216 -207
- wagtail/locale/tet/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/tet/LC_MESSAGES/django.po +40 -37
- wagtail/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/th/LC_MESSAGES/django.po +57 -53
- wagtail/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/tr/LC_MESSAGES/django.po +53 -50
- wagtail/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/tr_TR/LC_MESSAGES/django.po +53 -50
- wagtail/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ug/LC_MESSAGES/django.po +241 -232
- wagtail/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/uk/LC_MESSAGES/django.po +194 -185
- wagtail/locale/vi/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/vi/LC_MESSAGES/django.po +20 -19
- wagtail/locale/zh/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/zh/LC_MESSAGES/django.po +7 -4
- wagtail/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/zh_Hans/LC_MESSAGES/django.po +198 -189
- wagtail/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/zh_Hant/LC_MESSAGES/django.po +164 -161
- wagtail/locales/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/ca/LC_MESSAGES/django.po +13 -3
- wagtail/locales/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/de/LC_MESSAGES/django.po +13 -2
- wagtail/locales/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/en/LC_MESSAGES/django.po +26 -14
- wagtail/locales/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/fr/LC_MESSAGES/django.po +14 -2
- wagtail/locales/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/gl/LC_MESSAGES/django.po +13 -3
- wagtail/locales/locale/he_IL/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/hr_HR/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/is_IS/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nb/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pt_BR/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sk_SK/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tr_TR/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh_Hans/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/zh_Hant/LC_MESSAGES/django.po +3 -3
- wagtail/locales/tests.py +32 -1
- wagtail/locales/views.py +39 -7
- wagtail/models/__init__.py +67 -5002
- wagtail/models/audit_log.py +1 -1
- wagtail/models/content_types.py +11 -0
- wagtail/models/draft_state.py +197 -0
- wagtail/models/locking.py +82 -0
- wagtail/models/orderable.py +10 -0
- wagtail/models/pages.py +2755 -0
- wagtail/models/preview.py +281 -0
- wagtail/models/reference_index.py +1 -1
- wagtail/models/revisions.py +433 -0
- wagtail/models/view_restrictions.py +3 -3
- wagtail/models/workflows.py +1348 -0
- wagtail/project_template/home/apps.py +6 -0
- wagtail/project_template/manage.py-tpl +22 -0
- wagtail/project_template/project_name/settings/base.py +1 -0
- wagtail/project_template/requirements.txt +2 -2
- wagtail/search/backends/base.py +10 -5
- wagtail/search/backends/database/fallback.py +3 -0
- wagtail/search/backends/database/mysql/mysql.py +9 -2
- wagtail/search/backends/database/mysql/query.py +8 -4
- wagtail/search/backends/database/postgres/postgres.py +3 -0
- wagtail/search/backends/database/sqlite/sqlite.py +3 -0
- wagtail/search/backends/elasticsearch7.py +20 -7
- wagtail/search/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/search/signal_handlers.py +1 -1
- wagtail/search/tests/elasticsearch_common_tests.py +43 -0
- wagtail/search/tests/test_backends.py +50 -13
- wagtail/search/tests/test_index_functions.py +27 -1
- wagtail/search/tests/test_mysql_backend.py +97 -0
- wagtail/search/tests/test_page_search.py +2 -1
- wagtail/search/tests/test_queries.py +2 -2
- wagtail/signal_handlers.py +1 -1
- wagtail/sites/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/en_IN/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/es_VE/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/hi/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/sr/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/ta/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/sites/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/action_menu.py +9 -30
- wagtail/snippets/locale/af/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ar/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/az_AZ/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/be/LC_MESSAGES/django.po +6 -5
- wagtail/snippets/locale/bg/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/bn/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/ca/LC_MESSAGES/django.po +11 -13
- wagtail/snippets/locale/cs/LC_MESSAGES/django.po +5 -4
- wagtail/snippets/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/cy/LC_MESSAGES/django.po +5 -12
- wagtail/snippets/locale/da/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/de/LC_MESSAGES/django.po +13 -14
- wagtail/snippets/locale/dv/LC_MESSAGES/django.po +5 -4
- wagtail/snippets/locale/el/LC_MESSAGES/django.po +5 -4
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +31 -23
- wagtail/snippets/locale/en_IN/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/es/LC_MESSAGES/django.po +6 -13
- wagtail/snippets/locale/es_419/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/es_VE/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/et/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/fa/LC_MESSAGES/django.po +6 -5
- wagtail/snippets/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/fi/LC_MESSAGES/django.po +6 -9
- wagtail/snippets/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/fr/LC_MESSAGES/django.po +13 -14
- wagtail/snippets/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/gl/LC_MESSAGES/django.po +11 -13
- wagtail/snippets/locale/he_IL/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/hi/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.po +4 -12
- wagtail/snippets/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/hu/LC_MESSAGES/django.po +4 -12
- wagtail/snippets/locale/id_ID/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/is_IS/LC_MESSAGES/django.po +5 -14
- wagtail/snippets/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/it/LC_MESSAGES/django.po +5 -13
- wagtail/snippets/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/ja/LC_MESSAGES/django.po +6 -5
- wagtail/snippets/locale/ka/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/ko/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/lt/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/lv/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/mi/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/mn/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/my/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/nb/LC_MESSAGES/django.po +5 -12
- wagtail/snippets/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/nl/LC_MESSAGES/django.po +12 -13
- wagtail/snippets/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/pl/LC_MESSAGES/django.po +5 -13
- wagtail/snippets/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/pt_BR/LC_MESSAGES/django.po +7 -13
- wagtail/snippets/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/pt_PT/LC_MESSAGES/django.po +7 -5
- wagtail/snippets/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/ro/LC_MESSAGES/django.po +6 -13
- wagtail/snippets/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/ru/LC_MESSAGES/django.po +6 -13
- wagtail/snippets/locale/sk_SK/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/sl/LC_MESSAGES/django.po +5 -13
- wagtail/snippets/locale/sr/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/sv/LC_MESSAGES/django.po +5 -13
- wagtail/snippets/locale/ta/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/tet/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/th/LC_MESSAGES/django.po +6 -5
- wagtail/snippets/locale/tr/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/tr_TR/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/ug/LC_MESSAGES/django.po +4 -12
- wagtail/snippets/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/uk/LC_MESSAGES/django.po +6 -6
- wagtail/snippets/locale/vi/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/zh/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/zh_Hans/LC_MESSAGES/django.po +6 -13
- wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.po +4 -4
- wagtail/snippets/permissions.py +6 -4
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/publish.html +3 -5
- wagtail/snippets/tests/test_preview.py +62 -38
- wagtail/snippets/tests/test_snippets.py +313 -130
- wagtail/snippets/tests/test_viewset.py +69 -6
- wagtail/snippets/tests/test_workflows.py +0 -4
- wagtail/snippets/views/snippets.py +29 -53
- wagtail/snippets/wagtail_hooks.py +3 -7
- wagtail/templates/wagtailcore/shared/block_preview.html +9 -1
- wagtail/test/apps.py +5 -0
- wagtail/test/context_processors.py +19 -0
- wagtail/test/customuser/forms.py +19 -0
- wagtail/test/customuser/viewsets.py +12 -0
- wagtail/test/settings.py +8 -9
- wagtail/test/snippets/apps.py +10 -0
- wagtail/test/streamfield_migrations/testutils.py +4 -4
- wagtail/test/testapp/migrations/0046_alter_custom_rendition_to_unique_constraint.py +24 -0
- wagtail/test/testapp/migrations/0047_advertwithcustomuuidprimarykey_page.py +25 -0
- wagtail/test/testapp/migrations/0048_requireddatepage.py +36 -0
- wagtail/test/testapp/migrations/0049_promotionalpage.py +35 -0
- wagtail/test/testapp/migrations/0050_headcountrelatedmodelusingpk_related_page.py +25 -0
- wagtail/test/testapp/migrations/0051_userapprovaltaskstate_userapprovaltask.py +59 -0
- wagtail/test/testapp/models.py +190 -27
- wagtail/test/testapp/templates/tests/workflows/approve_with_style.html +6 -0
- wagtail/test/testapp/views.py +7 -1
- wagtail/test/testapp/wagtail_hooks.py +6 -0
- wagtail/test/utils/form_data.py +1 -0
- wagtail/tests/streamfield_migrations/test_migration_names.py +6 -6
- wagtail/tests/streamfield_migrations/test_migrations.py +46 -1
- wagtail/tests/test_blocks.py +11 -18
- wagtail/tests/test_management_commands.py +1 -1
- wagtail/tests/test_page_model.py +27 -0
- wagtail/tests/test_page_privacy.py +1 -1
- wagtail/tests/test_reference_index.py +39 -0
- wagtail/tests/test_streamfield.py +136 -0
- wagtail/tests/test_utils.py +1 -23
- wagtail/users/forms.py +3 -17
- wagtail/users/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/be/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/ca/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/cs/LC_MESSAGES/django.po +2 -1
- wagtail/users/locale/cy/LC_MESSAGES/django.po +2 -1
- wagtail/users/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/de/LC_MESSAGES/django.po +3 -3
- wagtail/users/locale/dv/LC_MESSAGES/django.po +2 -1
- wagtail/users/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/en/LC_MESSAGES/django.po +71 -71
- wagtail/users/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/fa/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/fi/LC_MESSAGES/django.po +4 -4
- wagtail/users/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/fr/LC_MESSAGES/django.po +4 -2
- wagtail/users/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/gl/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/hr_HR/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/hu/LC_MESSAGES/django.po +45 -3
- wagtail/users/locale/hy/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/it/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/ko/LC_MESSAGES/django.po +47 -2
- wagtail/users/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/mn/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/mn/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/nb/LC_MESSAGES/django.po +2 -1
- wagtail/users/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/nl/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/pl/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/pt_BR/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/pt_PT/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/ro/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/ru/LC_MESSAGES/django.po +4 -2
- wagtail/users/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/sk_SK/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/sl/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/sv/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/th/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/uk/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/vi/LC_MESSAGES/django.po +2 -1
- wagtail/users/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/zh_Hans/LC_MESSAGES/django.po +3 -2
- wagtail/users/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/users/models.py +7 -1
- wagtail/users/permission_order.py +16 -2
- wagtail/users/templatetags/wagtailusers_tags.py +3 -31
- wagtail/users/tests/__init__.py +0 -6
- wagtail/users/tests/test_admin_views.py +285 -611
- wagtail/users/views/groups.py +1 -28
- wagtail/users/views/users.py +3 -45
- wagtail/utils/deprecation.py +3 -3
- wagtail/whitelist.py +1 -0
- wagtail/workflows.py +2 -2
- wagtail-7.0.dist-info/METADATA +224 -0
- {wagtail-6.4rc1.dist-info → wagtail-7.0.dist-info}/RECORD +1648 -1631
- {wagtail-6.4rc1.dist-info → wagtail-7.0.dist-info}/WHEEL +1 -1
- wagtail/admin/templates/wagtailadmin/shared/ajax_pagination_nav.html +0 -25
- wagtail/contrib/redirects/locale/az_AZ/LC_MESSAGES/django.po +0 -22
- wagtail/contrib/search_promotions/locale/en_IN/LC_MESSAGES/django.po +0 -22
- wagtail/contrib/search_promotions/locale/hi/LC_MESSAGES/django.po +0 -22
- wagtail/contrib/search_promotions/locale/sr/LC_MESSAGES/django.po +0 -23
- wagtail/project_template/manage.py +0 -10
- wagtail/utils/setup.py +0 -90
- wagtail/utils/widgets.py +0 -46
- wagtail-6.4rc1.dist-info/METADATA +0 -77
- {wagtail-6.4rc1.dist-info → wagtail-7.0.dist-info}/entry_points.txt +0 -0
- {wagtail-6.4rc1.dist-info → wagtail-7.0.dist-info/licenses}/LICENSE +0 -0
- {wagtail-6.4rc1.dist-info → wagtail-7.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,1348 @@
|
|
|
1
|
+
from django import forms
|
|
2
|
+
from django.conf import settings
|
|
3
|
+
from django.contrib.auth.models import Group
|
|
4
|
+
from django.contrib.contenttypes.fields import GenericForeignKey
|
|
5
|
+
from django.contrib.contenttypes.models import ContentType
|
|
6
|
+
from django.core import checks
|
|
7
|
+
from django.core.exceptions import PermissionDenied, ValidationError
|
|
8
|
+
from django.db import models, transaction
|
|
9
|
+
from django.db.models import Q
|
|
10
|
+
from django.db.models.expressions import OuterRef, Subquery
|
|
11
|
+
from django.utils import timezone
|
|
12
|
+
from django.utils.functional import cached_property
|
|
13
|
+
from django.utils.module_loading import import_string
|
|
14
|
+
from django.utils.text import capfirst
|
|
15
|
+
from django.utils.translation import gettext_lazy as _
|
|
16
|
+
from modelcluster.fields import ParentalKey
|
|
17
|
+
from modelcluster.models import (
|
|
18
|
+
ClusterableModel,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from wagtail.coreutils import get_content_type_label
|
|
22
|
+
from wagtail.forms import TaskStateCommentForm
|
|
23
|
+
from wagtail.locks import WorkflowLock
|
|
24
|
+
from wagtail.log_actions import log
|
|
25
|
+
from wagtail.query import SpecificQuerySetMixin
|
|
26
|
+
from wagtail.signals import (
|
|
27
|
+
task_approved,
|
|
28
|
+
task_cancelled,
|
|
29
|
+
task_rejected,
|
|
30
|
+
task_submitted,
|
|
31
|
+
workflow_approved,
|
|
32
|
+
workflow_cancelled,
|
|
33
|
+
workflow_rejected,
|
|
34
|
+
workflow_submitted,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
from .copying import _copy, _copy_m2m_relations
|
|
38
|
+
from .draft_state import DraftStateMixin
|
|
39
|
+
from .locking import LockableMixin
|
|
40
|
+
from .orderable import Orderable
|
|
41
|
+
from .revisions import Revision, RevisionMixin
|
|
42
|
+
from .specific import SpecificMixin
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class WorkflowContentType(models.Model):
|
|
46
|
+
content_type = models.OneToOneField(
|
|
47
|
+
ContentType,
|
|
48
|
+
related_name="wagtail_workflow_content_type",
|
|
49
|
+
verbose_name=_("content type"),
|
|
50
|
+
on_delete=models.CASCADE,
|
|
51
|
+
primary_key=True,
|
|
52
|
+
unique=True,
|
|
53
|
+
)
|
|
54
|
+
workflow = models.ForeignKey(
|
|
55
|
+
"Workflow",
|
|
56
|
+
related_name="workflow_content_types",
|
|
57
|
+
verbose_name=_("workflow"),
|
|
58
|
+
on_delete=models.CASCADE,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def __str__(self):
|
|
62
|
+
content_type_label = get_content_type_label(self.content_type)
|
|
63
|
+
return f"WorkflowContentType: {content_type_label} - {self.workflow}"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class WorkflowStateQuerySet(models.QuerySet):
|
|
67
|
+
def active(self):
|
|
68
|
+
"""
|
|
69
|
+
Filters to only ``STATUS_IN_PROGRESS`` and ``STATUS_NEEDS_CHANGES`` WorkflowStates.
|
|
70
|
+
"""
|
|
71
|
+
return self.filter(
|
|
72
|
+
Q(status=WorkflowState.STATUS_IN_PROGRESS)
|
|
73
|
+
| Q(status=WorkflowState.STATUS_NEEDS_CHANGES)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
def for_instance(self, instance):
|
|
77
|
+
"""
|
|
78
|
+
Filters to only WorkflowStates for the given instance.
|
|
79
|
+
"""
|
|
80
|
+
try:
|
|
81
|
+
# Use RevisionMixin.get_base_content_type() if available
|
|
82
|
+
return self.filter(
|
|
83
|
+
base_content_type=instance.get_base_content_type(),
|
|
84
|
+
object_id=str(instance.pk),
|
|
85
|
+
)
|
|
86
|
+
except AttributeError:
|
|
87
|
+
# Fallback to ContentType for the model
|
|
88
|
+
return self.filter(
|
|
89
|
+
content_type=ContentType.objects.get_for_model(
|
|
90
|
+
instance, for_concrete_model=False
|
|
91
|
+
),
|
|
92
|
+
object_id=str(instance.pk),
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
WorkflowStateManager = models.Manager.from_queryset(WorkflowStateQuerySet)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class WorkflowState(models.Model):
|
|
100
|
+
"""Tracks the status of a started Workflow on an object."""
|
|
101
|
+
|
|
102
|
+
STATUS_IN_PROGRESS = "in_progress"
|
|
103
|
+
STATUS_APPROVED = "approved"
|
|
104
|
+
STATUS_NEEDS_CHANGES = "needs_changes"
|
|
105
|
+
STATUS_CANCELLED = "cancelled"
|
|
106
|
+
STATUS_CHOICES = (
|
|
107
|
+
(STATUS_IN_PROGRESS, _("In progress")),
|
|
108
|
+
(STATUS_APPROVED, _("Approved")),
|
|
109
|
+
(STATUS_NEEDS_CHANGES, _("Needs changes")),
|
|
110
|
+
(STATUS_CANCELLED, _("Cancelled")),
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
content_type = models.ForeignKey(
|
|
114
|
+
ContentType, on_delete=models.CASCADE, related_name="+"
|
|
115
|
+
)
|
|
116
|
+
base_content_type = models.ForeignKey(
|
|
117
|
+
ContentType, on_delete=models.CASCADE, related_name="+"
|
|
118
|
+
)
|
|
119
|
+
object_id = models.CharField(max_length=255, verbose_name=_("object id"))
|
|
120
|
+
|
|
121
|
+
content_object = GenericForeignKey(
|
|
122
|
+
"base_content_type", "object_id", for_concrete_model=False
|
|
123
|
+
)
|
|
124
|
+
content_object.wagtail_reference_index_ignore = True
|
|
125
|
+
|
|
126
|
+
workflow = models.ForeignKey(
|
|
127
|
+
"Workflow",
|
|
128
|
+
on_delete=models.CASCADE,
|
|
129
|
+
verbose_name=_("workflow"),
|
|
130
|
+
related_name="workflow_states",
|
|
131
|
+
)
|
|
132
|
+
status = models.fields.CharField(
|
|
133
|
+
choices=STATUS_CHOICES,
|
|
134
|
+
verbose_name=_("status"),
|
|
135
|
+
max_length=50,
|
|
136
|
+
default=STATUS_IN_PROGRESS,
|
|
137
|
+
)
|
|
138
|
+
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("created at"))
|
|
139
|
+
requested_by = models.ForeignKey(
|
|
140
|
+
settings.AUTH_USER_MODEL,
|
|
141
|
+
verbose_name=_("requested by"),
|
|
142
|
+
null=True,
|
|
143
|
+
blank=True,
|
|
144
|
+
editable=True,
|
|
145
|
+
on_delete=models.SET_NULL,
|
|
146
|
+
related_name="requested_workflows",
|
|
147
|
+
)
|
|
148
|
+
current_task_state = models.OneToOneField(
|
|
149
|
+
"TaskState",
|
|
150
|
+
on_delete=models.SET_NULL,
|
|
151
|
+
null=True,
|
|
152
|
+
blank=True,
|
|
153
|
+
verbose_name=_("current task state"),
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# allows a custom function to be called on finishing the Workflow successfully.
|
|
157
|
+
on_finish = import_string(
|
|
158
|
+
getattr(
|
|
159
|
+
settings,
|
|
160
|
+
"WAGTAIL_FINISH_WORKFLOW_ACTION",
|
|
161
|
+
"wagtail.workflows.publish_workflow_state",
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
objects = WorkflowStateManager()
|
|
166
|
+
|
|
167
|
+
def clean(self):
|
|
168
|
+
super().clean()
|
|
169
|
+
|
|
170
|
+
if self.status in (self.STATUS_IN_PROGRESS, self.STATUS_NEEDS_CHANGES):
|
|
171
|
+
# The unique constraint is conditional, and so not supported on the MySQL backend - so an additional check is done here
|
|
172
|
+
if (
|
|
173
|
+
WorkflowState.objects.active()
|
|
174
|
+
.filter(
|
|
175
|
+
base_content_type_id=self.base_content_type_id,
|
|
176
|
+
object_id=self.object_id,
|
|
177
|
+
)
|
|
178
|
+
.exclude(pk=self.pk)
|
|
179
|
+
.exists()
|
|
180
|
+
):
|
|
181
|
+
raise ValidationError(
|
|
182
|
+
_(
|
|
183
|
+
"There may only be one in progress or needs changes workflow state per page/snippet."
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
def save(self, *args, **kwargs):
|
|
188
|
+
self.full_clean()
|
|
189
|
+
return super().save(*args, **kwargs)
|
|
190
|
+
|
|
191
|
+
def __str__(self):
|
|
192
|
+
return _(
|
|
193
|
+
"Workflow '%(workflow_name)s' on %(model_name)s '%(title)s': %(status)s"
|
|
194
|
+
) % {
|
|
195
|
+
"workflow_name": self.workflow,
|
|
196
|
+
"model_name": self.content_object._meta.verbose_name,
|
|
197
|
+
"title": self.content_object,
|
|
198
|
+
"status": self.status,
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
def resume(self, user=None):
|
|
202
|
+
"""Put a STATUS_NEEDS_CHANGES workflow state back into STATUS_IN_PROGRESS, and restart the current task"""
|
|
203
|
+
from wagtail.models import Page
|
|
204
|
+
|
|
205
|
+
if self.status != self.STATUS_NEEDS_CHANGES:
|
|
206
|
+
raise PermissionDenied
|
|
207
|
+
revision = self.current_task_state.revision
|
|
208
|
+
current_task_state = self.current_task_state
|
|
209
|
+
self.current_task_state = None
|
|
210
|
+
self.status = self.STATUS_IN_PROGRESS
|
|
211
|
+
self.save()
|
|
212
|
+
|
|
213
|
+
instance = self.content_object
|
|
214
|
+
if isinstance(instance, Page):
|
|
215
|
+
instance = self.content_object.specific
|
|
216
|
+
|
|
217
|
+
log(
|
|
218
|
+
instance=instance,
|
|
219
|
+
action="wagtail.workflow.resume",
|
|
220
|
+
data={
|
|
221
|
+
"workflow": {
|
|
222
|
+
"id": self.workflow_id,
|
|
223
|
+
"title": self.workflow.name,
|
|
224
|
+
"status": self.status,
|
|
225
|
+
"task_state_id": current_task_state.id,
|
|
226
|
+
"task": {
|
|
227
|
+
"id": current_task_state.task.id,
|
|
228
|
+
"title": current_task_state.task.name,
|
|
229
|
+
},
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
revision=revision,
|
|
233
|
+
user=user,
|
|
234
|
+
)
|
|
235
|
+
return self.update(user=user, next_task=current_task_state.task)
|
|
236
|
+
|
|
237
|
+
def user_can_cancel(self, user):
|
|
238
|
+
if (
|
|
239
|
+
isinstance(self.content_object, LockableMixin)
|
|
240
|
+
and self.content_object.locked
|
|
241
|
+
and self.content_object.locked_by != user
|
|
242
|
+
):
|
|
243
|
+
return False
|
|
244
|
+
return (
|
|
245
|
+
user == self.requested_by
|
|
246
|
+
or user == getattr(self.content_object, "owner", None)
|
|
247
|
+
or (
|
|
248
|
+
self.current_task_state
|
|
249
|
+
and self.current_task_state.status
|
|
250
|
+
== self.current_task_state.STATUS_IN_PROGRESS
|
|
251
|
+
and "approve"
|
|
252
|
+
in [
|
|
253
|
+
action[0]
|
|
254
|
+
for action in self.current_task_state.task.get_actions(
|
|
255
|
+
self.content_object, user
|
|
256
|
+
)
|
|
257
|
+
]
|
|
258
|
+
)
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
def update(self, user=None, next_task=None):
|
|
262
|
+
"""
|
|
263
|
+
Checks the status of the current task, and progresses (or ends) the workflow if appropriate.
|
|
264
|
+
If the workflow progresses, next_task will be used to start a specific task next if provided.
|
|
265
|
+
"""
|
|
266
|
+
if self.status != self.STATUS_IN_PROGRESS:
|
|
267
|
+
# Updating a completed or cancelled workflow should have no effect
|
|
268
|
+
return
|
|
269
|
+
try:
|
|
270
|
+
current_status = self.current_task_state.status
|
|
271
|
+
except AttributeError:
|
|
272
|
+
current_status = None
|
|
273
|
+
if current_status == TaskState.STATUS_REJECTED:
|
|
274
|
+
self.status = self.STATUS_NEEDS_CHANGES
|
|
275
|
+
self.save()
|
|
276
|
+
workflow_rejected.send(sender=self.__class__, instance=self, user=user)
|
|
277
|
+
else:
|
|
278
|
+
if not next_task:
|
|
279
|
+
next_task = self.get_next_task()
|
|
280
|
+
if next_task:
|
|
281
|
+
if (
|
|
282
|
+
(not self.current_task_state)
|
|
283
|
+
or self.current_task_state.status
|
|
284
|
+
!= self.current_task_state.STATUS_IN_PROGRESS
|
|
285
|
+
):
|
|
286
|
+
# if not on a task, or the next task to move to is not the current task (ie current task's status is
|
|
287
|
+
# not STATUS_IN_PROGRESS), move to the next task
|
|
288
|
+
self.current_task_state = next_task.specific.start(self, user=user)
|
|
289
|
+
self.save()
|
|
290
|
+
# if task has auto-approved, update the workflow again
|
|
291
|
+
if (
|
|
292
|
+
self.current_task_state.status
|
|
293
|
+
!= self.current_task_state.STATUS_IN_PROGRESS
|
|
294
|
+
):
|
|
295
|
+
self.update(user=user)
|
|
296
|
+
# otherwise, continue on the current task
|
|
297
|
+
else:
|
|
298
|
+
# if there is no uncompleted task, finish the workflow.
|
|
299
|
+
self.finish(user=user)
|
|
300
|
+
|
|
301
|
+
@property
|
|
302
|
+
def successful_task_states(self):
|
|
303
|
+
successful_task_states = self.task_states.filter(
|
|
304
|
+
Q(status=TaskState.STATUS_APPROVED) | Q(status=TaskState.STATUS_SKIPPED)
|
|
305
|
+
)
|
|
306
|
+
if getattr(settings, "WAGTAIL_WORKFLOW_REQUIRE_REAPPROVAL_ON_EDIT", False):
|
|
307
|
+
successful_task_states = successful_task_states.filter(
|
|
308
|
+
revision=self.content_object.get_latest_revision()
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
return successful_task_states
|
|
312
|
+
|
|
313
|
+
def get_next_task(self):
|
|
314
|
+
"""
|
|
315
|
+
Returns the next active task, which has not been either approved or skipped.
|
|
316
|
+
"""
|
|
317
|
+
return (
|
|
318
|
+
Task.objects.filter(workflow_tasks__workflow=self.workflow, active=True)
|
|
319
|
+
.exclude(task_states__in=self.successful_task_states)
|
|
320
|
+
.order_by("workflow_tasks__sort_order")
|
|
321
|
+
.first()
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
def cancel(self, user=None):
|
|
325
|
+
"""Cancels the workflow state"""
|
|
326
|
+
from wagtail.models import Page
|
|
327
|
+
|
|
328
|
+
if self.status not in (self.STATUS_IN_PROGRESS, self.STATUS_NEEDS_CHANGES):
|
|
329
|
+
raise PermissionDenied
|
|
330
|
+
self.status = self.STATUS_CANCELLED
|
|
331
|
+
self.save()
|
|
332
|
+
|
|
333
|
+
instance = self.content_object
|
|
334
|
+
if isinstance(instance, Page):
|
|
335
|
+
instance = self.content_object.specific
|
|
336
|
+
|
|
337
|
+
log(
|
|
338
|
+
instance=instance,
|
|
339
|
+
action="wagtail.workflow.cancel",
|
|
340
|
+
data={
|
|
341
|
+
"workflow": {
|
|
342
|
+
"id": self.workflow_id,
|
|
343
|
+
"title": self.workflow.name,
|
|
344
|
+
"status": self.status,
|
|
345
|
+
"task_state_id": self.current_task_state.id,
|
|
346
|
+
"task": {
|
|
347
|
+
"id": self.current_task_state.task.id,
|
|
348
|
+
"title": self.current_task_state.task.name,
|
|
349
|
+
},
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
revision=self.current_task_state.revision,
|
|
353
|
+
user=user,
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
for state in self.task_states.filter(status=TaskState.STATUS_IN_PROGRESS):
|
|
357
|
+
# Cancel all in progress task states
|
|
358
|
+
state.specific.cancel(user=user)
|
|
359
|
+
workflow_cancelled.send(sender=self.__class__, instance=self, user=user)
|
|
360
|
+
|
|
361
|
+
@transaction.atomic
|
|
362
|
+
def finish(self, user=None):
|
|
363
|
+
"""
|
|
364
|
+
Finishes a successful in progress workflow, marking it as approved and performing the ``on_finish`` action.
|
|
365
|
+
"""
|
|
366
|
+
if self.status != self.STATUS_IN_PROGRESS:
|
|
367
|
+
raise PermissionDenied
|
|
368
|
+
self.status = self.STATUS_APPROVED
|
|
369
|
+
self.save()
|
|
370
|
+
self.on_finish(user=user)
|
|
371
|
+
workflow_approved.send(sender=self.__class__, instance=self, user=user)
|
|
372
|
+
|
|
373
|
+
def copy_approved_task_states_to_revision(self, revision):
|
|
374
|
+
"""
|
|
375
|
+
Creates copies of previously approved task states with revision set to a different revision.
|
|
376
|
+
"""
|
|
377
|
+
approved_states = TaskState.objects.filter(
|
|
378
|
+
workflow_state=self, status=TaskState.STATUS_APPROVED
|
|
379
|
+
)
|
|
380
|
+
for state in approved_states:
|
|
381
|
+
state.copy(update_attrs={"revision": revision})
|
|
382
|
+
|
|
383
|
+
def revisions(self):
|
|
384
|
+
"""
|
|
385
|
+
Returns all revisions associated with task states linked to the current workflow state.
|
|
386
|
+
"""
|
|
387
|
+
return Revision.objects.filter(
|
|
388
|
+
base_content_type_id=self.base_content_type_id,
|
|
389
|
+
object_id=self.object_id,
|
|
390
|
+
id__in=self.task_states.values_list("revision_id", flat=True),
|
|
391
|
+
).defer("content")
|
|
392
|
+
|
|
393
|
+
def _get_applicable_task_states(self):
|
|
394
|
+
"""
|
|
395
|
+
Returns the set of task states whose status applies to the current revision.
|
|
396
|
+
"""
|
|
397
|
+
task_states = TaskState.objects.filter(workflow_state_id=self.id)
|
|
398
|
+
# If WAGTAIL_WORKFLOW_REQUIRE_REAPPROVAL_ON_EDIT=True, this is only task states created on the current revision
|
|
399
|
+
if getattr(settings, "WAGTAIL_WORKFLOW_REQUIRE_REAPPROVAL_ON_EDIT", False):
|
|
400
|
+
latest_revision_id = (
|
|
401
|
+
self.revisions()
|
|
402
|
+
.order_by("-created_at", "-id")
|
|
403
|
+
.values_list("id", flat=True)
|
|
404
|
+
.first()
|
|
405
|
+
)
|
|
406
|
+
task_states = task_states.filter(revision_id=latest_revision_id)
|
|
407
|
+
return task_states
|
|
408
|
+
|
|
409
|
+
def all_tasks_with_status(self):
|
|
410
|
+
"""
|
|
411
|
+
Returns a list of Task objects that are linked with this workflow state's
|
|
412
|
+
workflow. The status of that task in this workflow state is annotated in the
|
|
413
|
+
``.status`` field. And a displayable version of that status is annotated in the
|
|
414
|
+
``.status_display`` field.
|
|
415
|
+
|
|
416
|
+
This is different to querying TaskState as it also returns tasks that haven't
|
|
417
|
+
been started yet (so won't have a TaskState).
|
|
418
|
+
"""
|
|
419
|
+
# Get the set of task states whose status applies to the current revision
|
|
420
|
+
task_states = self._get_applicable_task_states()
|
|
421
|
+
|
|
422
|
+
tasks = list(
|
|
423
|
+
self.workflow.tasks.annotate(
|
|
424
|
+
status=Subquery(
|
|
425
|
+
task_states.filter(
|
|
426
|
+
task_id=OuterRef("id"),
|
|
427
|
+
)
|
|
428
|
+
.order_by("-started_at", "-id")
|
|
429
|
+
.values("status")[:1]
|
|
430
|
+
),
|
|
431
|
+
)
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
# Manually annotate status_display
|
|
435
|
+
status_choices = dict(TaskState.STATUS_CHOICES)
|
|
436
|
+
for task in tasks:
|
|
437
|
+
task.status_display = status_choices.get(task.status, _("Not started"))
|
|
438
|
+
|
|
439
|
+
return tasks
|
|
440
|
+
|
|
441
|
+
def all_tasks_with_state(self):
|
|
442
|
+
"""
|
|
443
|
+
Returns a list of Task objects that are linked with this WorkflowState's
|
|
444
|
+
workflow, and have the latest task state.
|
|
445
|
+
|
|
446
|
+
In a "Submit for moderation -> reject at step 1 -> resubmit -> accept" workflow, this ensures
|
|
447
|
+
the task list reflects the accept, rather than the reject.
|
|
448
|
+
"""
|
|
449
|
+
task_states = self._get_applicable_task_states()
|
|
450
|
+
|
|
451
|
+
tasks = list(
|
|
452
|
+
self.workflow.tasks.annotate(
|
|
453
|
+
task_state_id=Subquery(
|
|
454
|
+
task_states.filter(
|
|
455
|
+
task_id=OuterRef("id"),
|
|
456
|
+
)
|
|
457
|
+
.order_by("-started_at", "-id")
|
|
458
|
+
.values("id")[:1]
|
|
459
|
+
),
|
|
460
|
+
)
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
task_states = {task_state.id: task_state for task_state in task_states}
|
|
464
|
+
# Manually annotate task_state
|
|
465
|
+
for task in tasks:
|
|
466
|
+
task.task_state = task_states.get(task.task_state_id)
|
|
467
|
+
|
|
468
|
+
return tasks
|
|
469
|
+
|
|
470
|
+
@property
|
|
471
|
+
def is_active(self):
|
|
472
|
+
return self.status not in [self.STATUS_APPROVED, self.STATUS_CANCELLED]
|
|
473
|
+
|
|
474
|
+
@property
|
|
475
|
+
def is_at_final_task(self):
|
|
476
|
+
"""
|
|
477
|
+
Returns the next active task, which has not been either approved or skipped.
|
|
478
|
+
"""
|
|
479
|
+
last_task = (
|
|
480
|
+
Task.objects.filter(workflow_tasks__workflow=self.workflow, active=True)
|
|
481
|
+
.exclude(task_states__in=self.successful_task_states)
|
|
482
|
+
.order_by("workflow_tasks__sort_order")
|
|
483
|
+
.last()
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
return self.get_next_task() == last_task
|
|
487
|
+
|
|
488
|
+
class Meta:
|
|
489
|
+
verbose_name = _("Workflow state")
|
|
490
|
+
verbose_name_plural = _("Workflow states")
|
|
491
|
+
# prevent multiple STATUS_IN_PROGRESS/STATUS_NEEDS_CHANGES workflows for the same object. This is only supported by specific databases (e.g. Postgres, SQL Server), so is checked additionally on save.
|
|
492
|
+
constraints = [
|
|
493
|
+
models.UniqueConstraint(
|
|
494
|
+
fields=["base_content_type", "object_id"],
|
|
495
|
+
condition=Q(status__in=("in_progress", "needs_changes")),
|
|
496
|
+
name="unique_in_progress_workflow",
|
|
497
|
+
)
|
|
498
|
+
]
|
|
499
|
+
indexes = [
|
|
500
|
+
models.Index(
|
|
501
|
+
fields=["content_type", "object_id"],
|
|
502
|
+
name="workflowstate_ct_id_idx",
|
|
503
|
+
),
|
|
504
|
+
models.Index(
|
|
505
|
+
fields=["base_content_type", "object_id"],
|
|
506
|
+
name="workflowstate_base_ct_id_idx",
|
|
507
|
+
),
|
|
508
|
+
]
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
class WorkflowManager(models.Manager):
|
|
512
|
+
def active(self):
|
|
513
|
+
return self.filter(active=True)
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
class AbstractWorkflow(ClusterableModel):
|
|
517
|
+
name = models.CharField(max_length=255, verbose_name=_("name"))
|
|
518
|
+
active = models.BooleanField(
|
|
519
|
+
verbose_name=_("active"),
|
|
520
|
+
default=True,
|
|
521
|
+
help_text=_(
|
|
522
|
+
"Active workflows can be added to pages/snippets. Deactivating a workflow does not remove it from existing pages/snippets."
|
|
523
|
+
),
|
|
524
|
+
)
|
|
525
|
+
objects = WorkflowManager()
|
|
526
|
+
|
|
527
|
+
def __str__(self):
|
|
528
|
+
return self.name
|
|
529
|
+
|
|
530
|
+
@property
|
|
531
|
+
def tasks(self):
|
|
532
|
+
"""
|
|
533
|
+
Returns all ``Task`` instances linked to this workflow.
|
|
534
|
+
"""
|
|
535
|
+
return Task.objects.filter(workflow_tasks__workflow=self).order_by(
|
|
536
|
+
"workflow_tasks__sort_order"
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
@transaction.atomic
|
|
540
|
+
def start(self, obj, user):
|
|
541
|
+
"""
|
|
542
|
+
Initiates a workflow by creating an instance of ``WorkflowState``.
|
|
543
|
+
"""
|
|
544
|
+
|
|
545
|
+
state = WorkflowState(
|
|
546
|
+
content_type=obj.get_content_type(),
|
|
547
|
+
base_content_type=obj.get_base_content_type(),
|
|
548
|
+
object_id=str(obj.pk),
|
|
549
|
+
workflow=self,
|
|
550
|
+
status=WorkflowState.STATUS_IN_PROGRESS,
|
|
551
|
+
requested_by=user,
|
|
552
|
+
)
|
|
553
|
+
state.save()
|
|
554
|
+
state.update(user=user)
|
|
555
|
+
workflow_submitted.send(sender=state.__class__, instance=state, user=user)
|
|
556
|
+
|
|
557
|
+
next_task_data = None
|
|
558
|
+
if state.current_task_state:
|
|
559
|
+
next_task_data = {
|
|
560
|
+
"id": state.current_task_state.task.id,
|
|
561
|
+
"title": state.current_task_state.task.name,
|
|
562
|
+
}
|
|
563
|
+
log(
|
|
564
|
+
instance=obj,
|
|
565
|
+
action="wagtail.workflow.start",
|
|
566
|
+
data={
|
|
567
|
+
"workflow": {
|
|
568
|
+
"id": self.id,
|
|
569
|
+
"title": self.name,
|
|
570
|
+
"status": state.status,
|
|
571
|
+
"next": next_task_data,
|
|
572
|
+
"task_state_id": state.current_task_state.id
|
|
573
|
+
if state.current_task_state
|
|
574
|
+
else None,
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
revision=obj.get_latest_revision(),
|
|
578
|
+
user=user,
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
return state
|
|
582
|
+
|
|
583
|
+
@transaction.atomic
|
|
584
|
+
def deactivate(self, user=None):
|
|
585
|
+
"""
|
|
586
|
+
Sets the workflow as inactive, and cancels all in progress instances of ``WorkflowState`` linked to this workflow.
|
|
587
|
+
"""
|
|
588
|
+
from wagtail.models import WorkflowPage
|
|
589
|
+
|
|
590
|
+
self.active = False
|
|
591
|
+
in_progress_states = WorkflowState.objects.filter(
|
|
592
|
+
workflow=self, status=WorkflowState.STATUS_IN_PROGRESS
|
|
593
|
+
)
|
|
594
|
+
for state in in_progress_states:
|
|
595
|
+
state.cancel(user=user)
|
|
596
|
+
WorkflowPage.objects.filter(workflow=self).delete()
|
|
597
|
+
WorkflowContentType.objects.filter(workflow=self).delete()
|
|
598
|
+
self.save()
|
|
599
|
+
|
|
600
|
+
def all_pages(self):
|
|
601
|
+
"""
|
|
602
|
+
Returns a queryset of all the pages that this Workflow applies to.
|
|
603
|
+
"""
|
|
604
|
+
from wagtail.models import Page
|
|
605
|
+
|
|
606
|
+
pages = Page.objects.none()
|
|
607
|
+
|
|
608
|
+
for workflow_page in self.workflow_pages.all():
|
|
609
|
+
pages |= workflow_page.get_pages()
|
|
610
|
+
|
|
611
|
+
return pages
|
|
612
|
+
|
|
613
|
+
class Meta:
|
|
614
|
+
verbose_name = _("workflow")
|
|
615
|
+
verbose_name_plural = _("workflows")
|
|
616
|
+
abstract = True
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
class Workflow(AbstractWorkflow):
|
|
620
|
+
pass
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
class WorkflowTask(Orderable):
|
|
624
|
+
workflow = ParentalKey(
|
|
625
|
+
"Workflow",
|
|
626
|
+
on_delete=models.CASCADE,
|
|
627
|
+
verbose_name=_("workflow_tasks"),
|
|
628
|
+
related_name="workflow_tasks",
|
|
629
|
+
)
|
|
630
|
+
task = models.ForeignKey(
|
|
631
|
+
"Task",
|
|
632
|
+
on_delete=models.CASCADE,
|
|
633
|
+
verbose_name=_("task"),
|
|
634
|
+
related_name="workflow_tasks",
|
|
635
|
+
limit_choices_to={"active": True},
|
|
636
|
+
)
|
|
637
|
+
|
|
638
|
+
class Meta(Orderable.Meta):
|
|
639
|
+
unique_together = [("workflow", "task")]
|
|
640
|
+
verbose_name = _("workflow task order")
|
|
641
|
+
verbose_name_plural = _("workflow task orders")
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
class TaskQuerySet(SpecificQuerySetMixin, models.QuerySet):
|
|
645
|
+
def active(self):
|
|
646
|
+
return self.filter(active=True)
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
TaskManager = models.Manager.from_queryset(TaskQuerySet)
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
class Task(SpecificMixin, models.Model):
|
|
653
|
+
name = models.CharField(max_length=255, verbose_name=_("name"))
|
|
654
|
+
content_type = models.ForeignKey(
|
|
655
|
+
ContentType,
|
|
656
|
+
verbose_name=_("content type"),
|
|
657
|
+
related_name="wagtail_tasks",
|
|
658
|
+
on_delete=models.CASCADE,
|
|
659
|
+
)
|
|
660
|
+
active = models.BooleanField(
|
|
661
|
+
verbose_name=_("active"),
|
|
662
|
+
default=True,
|
|
663
|
+
help_text=_(
|
|
664
|
+
"Active tasks can be added to workflows. Deactivating a task does not remove it from existing workflows."
|
|
665
|
+
),
|
|
666
|
+
)
|
|
667
|
+
objects = TaskManager()
|
|
668
|
+
|
|
669
|
+
admin_form_fields = ["name"]
|
|
670
|
+
admin_form_readonly_on_edit_fields = ["name"]
|
|
671
|
+
|
|
672
|
+
def __init__(self, *args, **kwargs):
|
|
673
|
+
super().__init__(*args, **kwargs)
|
|
674
|
+
if not self.id:
|
|
675
|
+
# this model is being newly created
|
|
676
|
+
# rather than retrieved from the db;
|
|
677
|
+
if not self.content_type_id:
|
|
678
|
+
# set content type to correctly represent the model class
|
|
679
|
+
# that this was created as
|
|
680
|
+
self.content_type = ContentType.objects.get_for_model(self)
|
|
681
|
+
|
|
682
|
+
def __str__(self):
|
|
683
|
+
return self.name
|
|
684
|
+
|
|
685
|
+
@property
|
|
686
|
+
def workflows(self):
|
|
687
|
+
"""
|
|
688
|
+
Returns all ``Workflow`` instances that use this task.
|
|
689
|
+
"""
|
|
690
|
+
return Workflow.objects.filter(workflow_tasks__task=self)
|
|
691
|
+
|
|
692
|
+
@property
|
|
693
|
+
def active_workflows(self):
|
|
694
|
+
"""
|
|
695
|
+
Return a ``QuerySet``` of active workflows that this task is part of.
|
|
696
|
+
"""
|
|
697
|
+
return Workflow.objects.active().filter(workflow_tasks__task=self)
|
|
698
|
+
|
|
699
|
+
@classmethod
|
|
700
|
+
def get_verbose_name(cls):
|
|
701
|
+
"""
|
|
702
|
+
Returns the human-readable "verbose name" of this task model e.g "Group approval task".
|
|
703
|
+
"""
|
|
704
|
+
# This is similar to doing cls._meta.verbose_name.title()
|
|
705
|
+
# except this doesn't convert any characters to lowercase
|
|
706
|
+
return capfirst(cls._meta.verbose_name)
|
|
707
|
+
|
|
708
|
+
task_state_class = None
|
|
709
|
+
|
|
710
|
+
@classmethod
|
|
711
|
+
def get_task_state_class(self):
|
|
712
|
+
return self.task_state_class or TaskState
|
|
713
|
+
|
|
714
|
+
def start(self, workflow_state, user=None):
|
|
715
|
+
"""
|
|
716
|
+
Start this task on the provided workflow state by creating an instance of TaskState.
|
|
717
|
+
"""
|
|
718
|
+
task_state = self.get_task_state_class()(workflow_state=workflow_state)
|
|
719
|
+
task_state.status = TaskState.STATUS_IN_PROGRESS
|
|
720
|
+
task_state.revision = workflow_state.content_object.get_latest_revision()
|
|
721
|
+
task_state.task = self
|
|
722
|
+
task_state.save()
|
|
723
|
+
task_submitted.send(
|
|
724
|
+
sender=task_state.specific.__class__,
|
|
725
|
+
instance=task_state.specific,
|
|
726
|
+
user=user,
|
|
727
|
+
)
|
|
728
|
+
return task_state
|
|
729
|
+
|
|
730
|
+
@transaction.atomic
|
|
731
|
+
def on_action(self, task_state, user, action_name, **kwargs):
|
|
732
|
+
"""
|
|
733
|
+
Performs an action on a task state determined by the ``action_name`` string passed.
|
|
734
|
+
"""
|
|
735
|
+
if action_name == "approve":
|
|
736
|
+
task_state.approve(user=user, **kwargs)
|
|
737
|
+
elif action_name == "reject":
|
|
738
|
+
task_state.reject(user=user, **kwargs)
|
|
739
|
+
|
|
740
|
+
def user_can_access_editor(self, obj, user):
|
|
741
|
+
"""
|
|
742
|
+
Returns ``True`` if a user who would not normally be able to access the editor for the
|
|
743
|
+
object should be able to if the object is currently on this task.
|
|
744
|
+
Note that returning ``False`` does not remove permissions from users who would otherwise have them.
|
|
745
|
+
"""
|
|
746
|
+
return False
|
|
747
|
+
|
|
748
|
+
def locked_for_user(self, obj, user):
|
|
749
|
+
"""
|
|
750
|
+
Returns ``True`` if the object should be locked to a given user's edits.
|
|
751
|
+
This can be used to prevent editing by non-reviewers.
|
|
752
|
+
"""
|
|
753
|
+
return False
|
|
754
|
+
|
|
755
|
+
def user_can_lock(self, obj, user):
|
|
756
|
+
"""
|
|
757
|
+
Returns ``True`` if a user who would not normally be able to lock the object should be able to
|
|
758
|
+
if the object is currently on this task.
|
|
759
|
+
Note that returning ``False`` does not remove permissions from users who would otherwise have them.
|
|
760
|
+
"""
|
|
761
|
+
return False
|
|
762
|
+
|
|
763
|
+
def user_can_unlock(self, obj, user):
|
|
764
|
+
"""
|
|
765
|
+
Returns ``True`` if a user who would not normally be able to unlock the object should be able to
|
|
766
|
+
if the object is currently on this task.
|
|
767
|
+
Note that returning ``False`` does not remove permissions from users who would otherwise have them.
|
|
768
|
+
"""
|
|
769
|
+
return False
|
|
770
|
+
|
|
771
|
+
def get_actions(self, obj, user):
|
|
772
|
+
"""
|
|
773
|
+
Get the list of action strings (name, verbose_name, whether the action requires additional data - see
|
|
774
|
+
``get_form_for_action``) for actions the current user can perform for this task on the given object.
|
|
775
|
+
These strings should be the same as those able to be passed to ``on_action``.
|
|
776
|
+
"""
|
|
777
|
+
return []
|
|
778
|
+
|
|
779
|
+
def get_form_for_action(self, action):
|
|
780
|
+
return TaskStateCommentForm
|
|
781
|
+
|
|
782
|
+
def get_template_for_action(self, action):
|
|
783
|
+
"""
|
|
784
|
+
Specifies a template for the workflow action modal.
|
|
785
|
+
"""
|
|
786
|
+
return ""
|
|
787
|
+
|
|
788
|
+
def get_task_states_user_can_moderate(self, user, **kwargs):
|
|
789
|
+
"""Returns a ``QuerySet`` of the task states the current user can moderate"""
|
|
790
|
+
return TaskState.objects.none()
|
|
791
|
+
|
|
792
|
+
@classmethod
|
|
793
|
+
def get_description(cls):
|
|
794
|
+
"""
|
|
795
|
+
Returns the task description.
|
|
796
|
+
"""
|
|
797
|
+
return ""
|
|
798
|
+
|
|
799
|
+
@transaction.atomic
|
|
800
|
+
def deactivate(self, user=None):
|
|
801
|
+
"""
|
|
802
|
+
Set ``active`` to False and cancel all in progress task states linked to this task.
|
|
803
|
+
"""
|
|
804
|
+
self.active = False
|
|
805
|
+
self.save()
|
|
806
|
+
in_progress_states = TaskState.objects.filter(
|
|
807
|
+
task=self, status=TaskState.STATUS_IN_PROGRESS
|
|
808
|
+
)
|
|
809
|
+
for state in in_progress_states:
|
|
810
|
+
state.cancel(user=user)
|
|
811
|
+
|
|
812
|
+
class Meta:
|
|
813
|
+
verbose_name = _("task")
|
|
814
|
+
verbose_name_plural = _("tasks")
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
class AbstractGroupApprovalTask(Task):
|
|
818
|
+
groups = models.ManyToManyField(
|
|
819
|
+
Group,
|
|
820
|
+
verbose_name=_("groups"),
|
|
821
|
+
help_text=_(
|
|
822
|
+
"Pages/snippets at this step in a workflow will be moderated or approved by these groups of users"
|
|
823
|
+
),
|
|
824
|
+
)
|
|
825
|
+
|
|
826
|
+
admin_form_fields = Task.admin_form_fields + ["groups"]
|
|
827
|
+
admin_form_widgets = {
|
|
828
|
+
"groups": forms.CheckboxSelectMultiple,
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
def start(self, workflow_state, user=None):
|
|
832
|
+
if (
|
|
833
|
+
isinstance(workflow_state.content_object, LockableMixin)
|
|
834
|
+
and workflow_state.content_object.locked_by
|
|
835
|
+
):
|
|
836
|
+
# If the person who locked the object isn't in one of the groups, unlock the object
|
|
837
|
+
if not workflow_state.content_object.locked_by.groups.filter(
|
|
838
|
+
id__in=self.groups.all()
|
|
839
|
+
).exists():
|
|
840
|
+
workflow_state.content_object.locked = False
|
|
841
|
+
workflow_state.content_object.locked_by = None
|
|
842
|
+
workflow_state.content_object.locked_at = None
|
|
843
|
+
workflow_state.content_object.save(
|
|
844
|
+
update_fields=["locked", "locked_by", "locked_at"]
|
|
845
|
+
)
|
|
846
|
+
|
|
847
|
+
return super().start(workflow_state, user=user)
|
|
848
|
+
|
|
849
|
+
def _user_in_groups(self, user):
|
|
850
|
+
# Cache the check whether "this user is in any of this
|
|
851
|
+
# GroupApprovalTask's groups" on the user object, in case we do it
|
|
852
|
+
# against the same user and task multiple times in a request.
|
|
853
|
+
# Use a dict to map the task id to the check result, in case we also
|
|
854
|
+
# check against different GroupApprovalTasks for the same user.
|
|
855
|
+
cache_attr = "_group_approval_task_checks"
|
|
856
|
+
if not (checks_cache := getattr(user, cache_attr, {})):
|
|
857
|
+
setattr(user, cache_attr, checks_cache)
|
|
858
|
+
|
|
859
|
+
if self.pk not in checks_cache:
|
|
860
|
+
checks_cache[self.pk] = self.groups.filter(
|
|
861
|
+
id__in=user.groups.all()
|
|
862
|
+
).exists()
|
|
863
|
+
|
|
864
|
+
return checks_cache[self.pk]
|
|
865
|
+
|
|
866
|
+
def user_can_access_editor(self, obj, user):
|
|
867
|
+
return user.is_superuser or self._user_in_groups(user)
|
|
868
|
+
|
|
869
|
+
def locked_for_user(self, obj, user):
|
|
870
|
+
return not (user.is_superuser or self._user_in_groups(user))
|
|
871
|
+
|
|
872
|
+
def user_can_lock(self, obj, user):
|
|
873
|
+
return self._user_in_groups(user)
|
|
874
|
+
|
|
875
|
+
def user_can_unlock(self, obj, user):
|
|
876
|
+
return False
|
|
877
|
+
|
|
878
|
+
def get_actions(self, obj, user):
|
|
879
|
+
if user.is_superuser or self._user_in_groups(user):
|
|
880
|
+
return [
|
|
881
|
+
("reject", _("Request changes"), True),
|
|
882
|
+
("approve", _("Approve"), False),
|
|
883
|
+
("approve", _("Approve with comment"), True),
|
|
884
|
+
]
|
|
885
|
+
|
|
886
|
+
return []
|
|
887
|
+
|
|
888
|
+
def get_task_states_user_can_moderate(self, user, **kwargs):
|
|
889
|
+
if user.is_superuser or self._user_in_groups(user):
|
|
890
|
+
return self.task_states.filter(status=TaskState.STATUS_IN_PROGRESS)
|
|
891
|
+
else:
|
|
892
|
+
return TaskState.objects.none()
|
|
893
|
+
|
|
894
|
+
@classmethod
|
|
895
|
+
def get_description(cls):
|
|
896
|
+
return _("Members of the chosen Wagtail Groups can approve this task")
|
|
897
|
+
|
|
898
|
+
class Meta:
|
|
899
|
+
abstract = True
|
|
900
|
+
verbose_name = _("Group approval task")
|
|
901
|
+
verbose_name_plural = _("Group approval tasks")
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
class GroupApprovalTask(AbstractGroupApprovalTask):
|
|
905
|
+
pass
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
class BaseTaskStateManager(models.Manager):
|
|
909
|
+
def reviewable_by(self, user):
|
|
910
|
+
tasks = Task.objects.filter(active=True).specific()
|
|
911
|
+
states = TaskState.objects.none()
|
|
912
|
+
for task in tasks:
|
|
913
|
+
states = states | task.get_task_states_user_can_moderate(user=user)
|
|
914
|
+
return states
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
class TaskStateQuerySet(SpecificQuerySetMixin, models.QuerySet):
|
|
918
|
+
def for_instance(self, instance):
|
|
919
|
+
"""
|
|
920
|
+
Filters to only TaskStates for the given instance
|
|
921
|
+
"""
|
|
922
|
+
try:
|
|
923
|
+
# Use RevisionMixin.get_base_content_type() if available
|
|
924
|
+
return self.filter(
|
|
925
|
+
workflow_state__base_content_type=instance.get_base_content_type(),
|
|
926
|
+
workflow_state__object_id=str(instance.pk),
|
|
927
|
+
)
|
|
928
|
+
except AttributeError:
|
|
929
|
+
# Fallback to ContentType for the model
|
|
930
|
+
return self.filter(
|
|
931
|
+
workflow_state__content_type=ContentType.objects.get_for_model(
|
|
932
|
+
instance, for_concrete_model=False
|
|
933
|
+
),
|
|
934
|
+
workflow_state__object_id=str(instance.pk),
|
|
935
|
+
)
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
TaskStateManager = BaseTaskStateManager.from_queryset(TaskStateQuerySet)
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
class TaskState(SpecificMixin, models.Model):
|
|
942
|
+
"""Tracks the status of a given Task for a particular revision."""
|
|
943
|
+
|
|
944
|
+
STATUS_IN_PROGRESS = "in_progress"
|
|
945
|
+
STATUS_APPROVED = "approved"
|
|
946
|
+
STATUS_REJECTED = "rejected"
|
|
947
|
+
STATUS_SKIPPED = "skipped"
|
|
948
|
+
STATUS_CANCELLED = "cancelled"
|
|
949
|
+
STATUS_CHOICES = (
|
|
950
|
+
(STATUS_IN_PROGRESS, _("In progress")),
|
|
951
|
+
(STATUS_APPROVED, _("Approved")),
|
|
952
|
+
(STATUS_REJECTED, _("Rejected")),
|
|
953
|
+
(STATUS_SKIPPED, _("Skipped")),
|
|
954
|
+
(STATUS_CANCELLED, _("Cancelled")),
|
|
955
|
+
)
|
|
956
|
+
|
|
957
|
+
workflow_state = models.ForeignKey(
|
|
958
|
+
"WorkflowState",
|
|
959
|
+
on_delete=models.CASCADE,
|
|
960
|
+
verbose_name=_("workflow state"),
|
|
961
|
+
related_name="task_states",
|
|
962
|
+
)
|
|
963
|
+
revision = models.ForeignKey(
|
|
964
|
+
"Revision",
|
|
965
|
+
on_delete=models.CASCADE,
|
|
966
|
+
verbose_name=_("revision"),
|
|
967
|
+
related_name="task_states",
|
|
968
|
+
)
|
|
969
|
+
task = models.ForeignKey(
|
|
970
|
+
"Task",
|
|
971
|
+
on_delete=models.CASCADE,
|
|
972
|
+
verbose_name=_("task"),
|
|
973
|
+
related_name="task_states",
|
|
974
|
+
)
|
|
975
|
+
status = models.fields.CharField(
|
|
976
|
+
choices=STATUS_CHOICES,
|
|
977
|
+
verbose_name=_("status"),
|
|
978
|
+
max_length=50,
|
|
979
|
+
default=STATUS_IN_PROGRESS,
|
|
980
|
+
)
|
|
981
|
+
started_at = models.DateTimeField(verbose_name=_("started at"), auto_now_add=True)
|
|
982
|
+
finished_at = models.DateTimeField(
|
|
983
|
+
verbose_name=_("finished at"), blank=True, null=True
|
|
984
|
+
)
|
|
985
|
+
finished_by = models.ForeignKey(
|
|
986
|
+
settings.AUTH_USER_MODEL,
|
|
987
|
+
verbose_name=_("finished by"),
|
|
988
|
+
null=True,
|
|
989
|
+
blank=True,
|
|
990
|
+
on_delete=models.SET_NULL,
|
|
991
|
+
related_name="finished_task_states",
|
|
992
|
+
)
|
|
993
|
+
comment = models.TextField(blank=True)
|
|
994
|
+
content_type = models.ForeignKey(
|
|
995
|
+
ContentType,
|
|
996
|
+
verbose_name=_("content type"),
|
|
997
|
+
related_name="wagtail_task_states",
|
|
998
|
+
on_delete=models.CASCADE,
|
|
999
|
+
)
|
|
1000
|
+
exclude_fields_in_copy = []
|
|
1001
|
+
default_exclude_fields_in_copy = ["id"]
|
|
1002
|
+
|
|
1003
|
+
objects = TaskStateManager()
|
|
1004
|
+
|
|
1005
|
+
def __init__(self, *args, **kwargs):
|
|
1006
|
+
super().__init__(*args, **kwargs)
|
|
1007
|
+
if not self.id:
|
|
1008
|
+
# this model is being newly created
|
|
1009
|
+
# rather than retrieved from the db;
|
|
1010
|
+
if not self.content_type_id:
|
|
1011
|
+
# set content type to correctly represent the model class
|
|
1012
|
+
# that this was created as
|
|
1013
|
+
self.content_type = ContentType.objects.get_for_model(self)
|
|
1014
|
+
|
|
1015
|
+
def __str__(self):
|
|
1016
|
+
return _("Task '%(task_name)s' on Revision '%(revision_info)s': %(status)s") % {
|
|
1017
|
+
"task_name": self.task,
|
|
1018
|
+
"revision_info": self.revision,
|
|
1019
|
+
"status": self.status,
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
@transaction.atomic
|
|
1023
|
+
def approve(self, user=None, update=True, comment=""):
|
|
1024
|
+
"""
|
|
1025
|
+
Approve the task state and update the workflow state.
|
|
1026
|
+
"""
|
|
1027
|
+
if self.status != self.STATUS_IN_PROGRESS:
|
|
1028
|
+
raise PermissionDenied
|
|
1029
|
+
self.status = self.STATUS_APPROVED
|
|
1030
|
+
self.finished_at = timezone.now()
|
|
1031
|
+
self.finished_by = user
|
|
1032
|
+
self.comment = comment
|
|
1033
|
+
self.save()
|
|
1034
|
+
|
|
1035
|
+
self.log_state_change_action(user, "approve")
|
|
1036
|
+
if update:
|
|
1037
|
+
self.workflow_state.update(user=user)
|
|
1038
|
+
task_approved.send(
|
|
1039
|
+
sender=self.specific.__class__, instance=self.specific, user=user
|
|
1040
|
+
)
|
|
1041
|
+
return self
|
|
1042
|
+
|
|
1043
|
+
@transaction.atomic
|
|
1044
|
+
def reject(self, user=None, update=True, comment=""):
|
|
1045
|
+
"""
|
|
1046
|
+
Reject the task state and update the workflow state.
|
|
1047
|
+
"""
|
|
1048
|
+
if self.status != self.STATUS_IN_PROGRESS:
|
|
1049
|
+
raise PermissionDenied
|
|
1050
|
+
self.status = self.STATUS_REJECTED
|
|
1051
|
+
self.finished_at = timezone.now()
|
|
1052
|
+
self.finished_by = user
|
|
1053
|
+
self.comment = comment
|
|
1054
|
+
self.save()
|
|
1055
|
+
|
|
1056
|
+
self.log_state_change_action(user, "reject")
|
|
1057
|
+
if update:
|
|
1058
|
+
self.workflow_state.update(user=user)
|
|
1059
|
+
task_rejected.send(
|
|
1060
|
+
sender=self.specific.__class__, instance=self.specific, user=user
|
|
1061
|
+
)
|
|
1062
|
+
|
|
1063
|
+
return self
|
|
1064
|
+
|
|
1065
|
+
@cached_property
|
|
1066
|
+
def task_type_started_at(self):
|
|
1067
|
+
"""
|
|
1068
|
+
Finds the first chronological started_at for successive TaskStates - ie started_at if the task had not been restarted.
|
|
1069
|
+
"""
|
|
1070
|
+
task_states = (
|
|
1071
|
+
TaskState.objects.filter(workflow_state=self.workflow_state)
|
|
1072
|
+
.order_by("-started_at")
|
|
1073
|
+
.select_related("task")
|
|
1074
|
+
)
|
|
1075
|
+
started_at = None
|
|
1076
|
+
for task_state in task_states:
|
|
1077
|
+
if task_state.task == self.task:
|
|
1078
|
+
started_at = task_state.started_at
|
|
1079
|
+
elif started_at:
|
|
1080
|
+
break
|
|
1081
|
+
return started_at
|
|
1082
|
+
|
|
1083
|
+
@transaction.atomic
|
|
1084
|
+
def cancel(self, user=None, resume=False, comment=""):
|
|
1085
|
+
"""
|
|
1086
|
+
Cancel the task state and update the workflow state.
|
|
1087
|
+
If ``resume`` is set to True, then upon update the workflow state is passed the current task as ``next_task``,
|
|
1088
|
+
causing it to start a new task state on the current task if possible.
|
|
1089
|
+
"""
|
|
1090
|
+
self.status = self.STATUS_CANCELLED
|
|
1091
|
+
self.finished_at = timezone.now()
|
|
1092
|
+
self.comment = comment
|
|
1093
|
+
self.finished_by = user
|
|
1094
|
+
self.save()
|
|
1095
|
+
if resume:
|
|
1096
|
+
self.workflow_state.update(user=user, next_task=self.task.specific)
|
|
1097
|
+
else:
|
|
1098
|
+
self.workflow_state.update(user=user)
|
|
1099
|
+
task_cancelled.send(
|
|
1100
|
+
sender=self.specific.__class__, instance=self.specific, user=user
|
|
1101
|
+
)
|
|
1102
|
+
return self
|
|
1103
|
+
|
|
1104
|
+
def copy(self, update_attrs=None, exclude_fields=None):
|
|
1105
|
+
"""
|
|
1106
|
+
Copy this task state, excluding the attributes in the ``exclude_fields`` list and updating any attributes
|
|
1107
|
+
to values specified in the ``update_attrs`` dictionary of ``attribute``: ``new value`` pairs.
|
|
1108
|
+
"""
|
|
1109
|
+
exclude_fields = (
|
|
1110
|
+
self.default_exclude_fields_in_copy
|
|
1111
|
+
+ self.exclude_fields_in_copy
|
|
1112
|
+
+ (exclude_fields or [])
|
|
1113
|
+
)
|
|
1114
|
+
instance, child_object_map = _copy(self.specific, exclude_fields, update_attrs)
|
|
1115
|
+
instance.save()
|
|
1116
|
+
_copy_m2m_relations(self, instance, exclude_fields=exclude_fields)
|
|
1117
|
+
return instance
|
|
1118
|
+
|
|
1119
|
+
def get_comment(self):
|
|
1120
|
+
"""
|
|
1121
|
+
Returns a string that is displayed in workflow history.
|
|
1122
|
+
|
|
1123
|
+
This could be a comment by the reviewer, or generated.
|
|
1124
|
+
Use mark_safe to return HTML.
|
|
1125
|
+
"""
|
|
1126
|
+
return self.comment
|
|
1127
|
+
|
|
1128
|
+
def log_state_change_action(self, user, action):
|
|
1129
|
+
"""Log the approval/rejection action"""
|
|
1130
|
+
obj = self.revision.as_object()
|
|
1131
|
+
next_task = self.workflow_state.get_next_task()
|
|
1132
|
+
next_task_data = None
|
|
1133
|
+
if next_task:
|
|
1134
|
+
next_task_data = {"id": next_task.id, "title": next_task.name}
|
|
1135
|
+
log(
|
|
1136
|
+
instance=obj,
|
|
1137
|
+
action=f"wagtail.workflow.{action}",
|
|
1138
|
+
user=user,
|
|
1139
|
+
data={
|
|
1140
|
+
"workflow": {
|
|
1141
|
+
"id": self.workflow_state.workflow.id,
|
|
1142
|
+
"title": self.workflow_state.workflow.name,
|
|
1143
|
+
"status": self.status,
|
|
1144
|
+
"task_state_id": self.id,
|
|
1145
|
+
"task": {
|
|
1146
|
+
"id": self.task.id,
|
|
1147
|
+
"title": self.task.name,
|
|
1148
|
+
},
|
|
1149
|
+
"next": next_task_data,
|
|
1150
|
+
},
|
|
1151
|
+
"comment": self.get_comment(),
|
|
1152
|
+
},
|
|
1153
|
+
revision=self.revision,
|
|
1154
|
+
)
|
|
1155
|
+
|
|
1156
|
+
class Meta:
|
|
1157
|
+
verbose_name = _("Task state")
|
|
1158
|
+
verbose_name_plural = _("Task states")
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
class WorkflowMixin:
|
|
1162
|
+
"""A mixin that allows a model to have workflows."""
|
|
1163
|
+
|
|
1164
|
+
@classmethod
|
|
1165
|
+
def check(cls, **kwargs):
|
|
1166
|
+
return [
|
|
1167
|
+
*super().check(**kwargs),
|
|
1168
|
+
*cls._check_draftstate_and_revision_mixins(),
|
|
1169
|
+
]
|
|
1170
|
+
|
|
1171
|
+
@classmethod
|
|
1172
|
+
def _check_draftstate_and_revision_mixins(cls):
|
|
1173
|
+
mro = cls.mro()
|
|
1174
|
+
error = checks.Error(
|
|
1175
|
+
"WorkflowMixin requires DraftStateMixin and RevisionMixin (in that order).",
|
|
1176
|
+
hint=(
|
|
1177
|
+
"Make sure your model's inheritance order is as follows: "
|
|
1178
|
+
"WorkflowMixin, DraftStateMixin, RevisionMixin."
|
|
1179
|
+
),
|
|
1180
|
+
obj=cls,
|
|
1181
|
+
id="wagtailcore.E006",
|
|
1182
|
+
)
|
|
1183
|
+
|
|
1184
|
+
try:
|
|
1185
|
+
if not (
|
|
1186
|
+
mro.index(WorkflowMixin)
|
|
1187
|
+
< mro.index(DraftStateMixin)
|
|
1188
|
+
< mro.index(RevisionMixin)
|
|
1189
|
+
):
|
|
1190
|
+
return [error]
|
|
1191
|
+
except ValueError:
|
|
1192
|
+
return [error]
|
|
1193
|
+
|
|
1194
|
+
return []
|
|
1195
|
+
|
|
1196
|
+
@classmethod
|
|
1197
|
+
def get_default_workflow(cls):
|
|
1198
|
+
"""
|
|
1199
|
+
Returns the active workflow assigned to the model.
|
|
1200
|
+
|
|
1201
|
+
For non-``Page`` models, workflows are assigned to the model's content type,
|
|
1202
|
+
thus shared across all instances instead of being assigned to individual
|
|
1203
|
+
instances (unless :meth:`~WorkflowMixin.get_workflow` is overridden).
|
|
1204
|
+
|
|
1205
|
+
This method is used to determine the workflow to use when creating new
|
|
1206
|
+
instances of the model. On ``Page`` models, this method is unused as the
|
|
1207
|
+
workflow can be determined from the parent page's workflow.
|
|
1208
|
+
"""
|
|
1209
|
+
if not getattr(settings, "WAGTAIL_WORKFLOW_ENABLED", True):
|
|
1210
|
+
return None
|
|
1211
|
+
|
|
1212
|
+
content_type = ContentType.objects.get_for_model(cls, for_concrete_model=False)
|
|
1213
|
+
workflow_content_type = (
|
|
1214
|
+
WorkflowContentType.objects.filter(
|
|
1215
|
+
workflow__active=True,
|
|
1216
|
+
content_type=content_type,
|
|
1217
|
+
)
|
|
1218
|
+
.select_related("workflow")
|
|
1219
|
+
.first()
|
|
1220
|
+
)
|
|
1221
|
+
|
|
1222
|
+
if workflow_content_type:
|
|
1223
|
+
return workflow_content_type.workflow
|
|
1224
|
+
return None
|
|
1225
|
+
|
|
1226
|
+
@property
|
|
1227
|
+
def has_workflow(self):
|
|
1228
|
+
"""
|
|
1229
|
+
Returns ```True``` if the object has an active workflow assigned, otherwise ```False```.
|
|
1230
|
+
"""
|
|
1231
|
+
return self.get_workflow() is not None
|
|
1232
|
+
|
|
1233
|
+
def get_workflow(self):
|
|
1234
|
+
"""
|
|
1235
|
+
Returns the active workflow assigned to the object.
|
|
1236
|
+
"""
|
|
1237
|
+
return self.get_default_workflow()
|
|
1238
|
+
|
|
1239
|
+
@property
|
|
1240
|
+
def workflow_states(self):
|
|
1241
|
+
"""
|
|
1242
|
+
Returns workflow states that belong to the object.
|
|
1243
|
+
|
|
1244
|
+
To allow filtering ``WorkflowState`` queries by the object,
|
|
1245
|
+
subclasses should define a
|
|
1246
|
+
:class:`~django.contrib.contenttypes.fields.GenericRelation` to
|
|
1247
|
+
:class:`~wagtail.models.WorkflowState` with the desired
|
|
1248
|
+
``related_query_name``. This property can be replaced with the
|
|
1249
|
+
``GenericRelation`` or overridden to allow custom logic, which can be
|
|
1250
|
+
useful if the model has inheritance.
|
|
1251
|
+
"""
|
|
1252
|
+
return WorkflowState.objects.for_instance(self)
|
|
1253
|
+
|
|
1254
|
+
@property
|
|
1255
|
+
def workflow_in_progress(self):
|
|
1256
|
+
"""
|
|
1257
|
+
Returns ```True``` if a workflow is in progress on the current object, otherwise ```False```.
|
|
1258
|
+
"""
|
|
1259
|
+
if not getattr(settings, "WAGTAIL_WORKFLOW_ENABLED", True):
|
|
1260
|
+
return False
|
|
1261
|
+
|
|
1262
|
+
# `_current_workflow_states` may be populated by `prefetch_workflow_states`
|
|
1263
|
+
# on querysets as a performance optimization
|
|
1264
|
+
if hasattr(self, "_current_workflow_states"):
|
|
1265
|
+
for state in self._current_workflow_states:
|
|
1266
|
+
if state.status == WorkflowState.STATUS_IN_PROGRESS:
|
|
1267
|
+
return True
|
|
1268
|
+
return False
|
|
1269
|
+
|
|
1270
|
+
return self.workflow_states.filter(
|
|
1271
|
+
status=WorkflowState.STATUS_IN_PROGRESS
|
|
1272
|
+
).exists()
|
|
1273
|
+
|
|
1274
|
+
@property
|
|
1275
|
+
def current_workflow_state(self):
|
|
1276
|
+
"""
|
|
1277
|
+
Returns the in progress or needs changes workflow state on this object, if it exists.
|
|
1278
|
+
"""
|
|
1279
|
+
if not getattr(settings, "WAGTAIL_WORKFLOW_ENABLED", True):
|
|
1280
|
+
return None
|
|
1281
|
+
|
|
1282
|
+
# `_current_workflow_states` may be populated by `prefetch_workflow_states`
|
|
1283
|
+
# on querysets as a performance optimization
|
|
1284
|
+
if hasattr(self, "_current_workflow_states"):
|
|
1285
|
+
try:
|
|
1286
|
+
return self._current_workflow_states[0]
|
|
1287
|
+
except IndexError:
|
|
1288
|
+
return
|
|
1289
|
+
|
|
1290
|
+
return (
|
|
1291
|
+
self.workflow_states.active()
|
|
1292
|
+
.select_related("current_task_state__task")
|
|
1293
|
+
.first()
|
|
1294
|
+
)
|
|
1295
|
+
|
|
1296
|
+
@property
|
|
1297
|
+
def current_workflow_task_state(self):
|
|
1298
|
+
"""
|
|
1299
|
+
Returns (specific class of) the current task state of the workflow on this object, if it exists.
|
|
1300
|
+
"""
|
|
1301
|
+
current_workflow_state = self.current_workflow_state
|
|
1302
|
+
if (
|
|
1303
|
+
current_workflow_state
|
|
1304
|
+
and current_workflow_state.status == WorkflowState.STATUS_IN_PROGRESS
|
|
1305
|
+
and current_workflow_state.current_task_state
|
|
1306
|
+
):
|
|
1307
|
+
return current_workflow_state.current_task_state.specific
|
|
1308
|
+
|
|
1309
|
+
@property
|
|
1310
|
+
def current_workflow_task(self):
|
|
1311
|
+
"""
|
|
1312
|
+
Returns (specific class of) the current task in progress on this object, if it exists.
|
|
1313
|
+
"""
|
|
1314
|
+
current_workflow_task_state = self.current_workflow_task_state
|
|
1315
|
+
if current_workflow_task_state:
|
|
1316
|
+
return current_workflow_task_state.task.specific
|
|
1317
|
+
|
|
1318
|
+
@property
|
|
1319
|
+
def status_string(self):
|
|
1320
|
+
if not self.live:
|
|
1321
|
+
if self.expired:
|
|
1322
|
+
return _("expired")
|
|
1323
|
+
elif self.approved_schedule:
|
|
1324
|
+
return _("scheduled")
|
|
1325
|
+
elif self.workflow_in_progress:
|
|
1326
|
+
return _("in moderation")
|
|
1327
|
+
else:
|
|
1328
|
+
return _("draft")
|
|
1329
|
+
else:
|
|
1330
|
+
if self.approved_schedule:
|
|
1331
|
+
return _("live + scheduled")
|
|
1332
|
+
elif self.workflow_in_progress:
|
|
1333
|
+
return _("live + in moderation")
|
|
1334
|
+
elif self.has_unpublished_changes:
|
|
1335
|
+
return _("live + draft")
|
|
1336
|
+
else:
|
|
1337
|
+
return _("live")
|
|
1338
|
+
|
|
1339
|
+
def get_lock(self):
|
|
1340
|
+
# Standard locking should take precedence over workflow locking
|
|
1341
|
+
# because it's possible for both to be used at the same time
|
|
1342
|
+
lock = super().get_lock()
|
|
1343
|
+
if lock:
|
|
1344
|
+
return lock
|
|
1345
|
+
|
|
1346
|
+
current_workflow_task = self.current_workflow_task
|
|
1347
|
+
if current_workflow_task:
|
|
1348
|
+
return WorkflowLock(self, current_workflow_task)
|