wagtail 7.1.2__py3-none-any.whl → 7.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wagtail/__init__.py +1 -1
- wagtail/actions/copy_page.py +1 -1
- wagtail/actions/create_alias.py +1 -1
- wagtail/actions/delete_page.py +1 -1
- wagtail/actions/publish_page_revision.py +1 -1
- wagtail/actions/publish_revision.py +1 -1
- wagtail/actions/revert_to_page_revision.py +1 -1
- wagtail/actions/unpublish.py +1 -1
- wagtail/actions/unpublish_page.py +1 -1
- wagtail/admin/auth.py +3 -1
- wagtail/admin/checks.py +2 -2
- wagtail/admin/filters.py +28 -1
- wagtail/admin/forms/collections.py +1 -1
- wagtail/admin/forms/comments.py +1 -1
- wagtail/admin/forms/models.py +1 -1
- wagtail/admin/forms/pages.py +1 -1
- wagtail/admin/forms/tags.py +1 -1
- wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ar/LC_MESSAGES/django.po +44 -89
- wagtail/admin/locale/az_AZ/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/az_AZ/LC_MESSAGES/django.po +4 -7
- wagtail/admin/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/be/LC_MESSAGES/django.po +15 -42
- wagtail/admin/locale/bg/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/bg/LC_MESSAGES/django.po +7 -16
- wagtail/admin/locale/bn/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/bn/LC_MESSAGES/django.po +4 -13
- wagtail/admin/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ca/LC_MESSAGES/django.po +159 -74
- wagtail/admin/locale/ca/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/ca/LC_MESSAGES/djangojs.po +11 -0
- wagtail/admin/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/cs/LC_MESSAGES/django.po +40 -50
- wagtail/admin/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/cy/LC_MESSAGES/django.po +6 -13
- wagtail/admin/locale/da/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/da/LC_MESSAGES/django.po +10 -22
- wagtail/admin/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/de/LC_MESSAGES/django.po +42 -93
- wagtail/admin/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/dv/LC_MESSAGES/django.po +26 -64
- wagtail/admin/locale/el/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/el/LC_MESSAGES/django.po +9 -31
- wagtail/admin/locale/en/LC_MESSAGES/django.po +278 -192
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +29 -15
- wagtail/admin/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/es/LC_MESSAGES/django.po +17 -52
- wagtail/admin/locale/es_419/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/es_419/LC_MESSAGES/django.po +4 -22
- wagtail/admin/locale/es_VE/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/es_VE/LC_MESSAGES/django.po +4 -7
- wagtail/admin/locale/et/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/et/LC_MESSAGES/django.po +15 -42
- wagtail/admin/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/admin/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/fa/LC_MESSAGES/django.po +12 -50
- wagtail/admin/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/fi/LC_MESSAGES/django.po +43 -70
- wagtail/admin/locale/fi/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/fi/LC_MESSAGES/djangojs.po +17 -0
- wagtail/admin/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/fr/LC_MESSAGES/django.po +157 -74
- wagtail/admin/locale/fr/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/fr/LC_MESSAGES/djangojs.po +11 -0
- wagtail/admin/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/gl/LC_MESSAGES/django.po +155 -72
- wagtail/admin/locale/gl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/gl/LC_MESSAGES/djangojs.po +11 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.po +7 -28
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.po +15 -38
- wagtail/admin/locale/ht/LC_MESSAGES/django.po +4 -4
- wagtail/admin/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hu/LC_MESSAGES/django.po +44 -91
- wagtail/admin/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/id_ID/LC_MESSAGES/django.po +10 -31
- wagtail/admin/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/is_IS/LC_MESSAGES/django.po +41 -87
- wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/django.po +34 -78
- wagtail/admin/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ja/LC_MESSAGES/django.po +15 -42
- wagtail/admin/locale/ka/LC_MESSAGES/django.po +4 -4
- wagtail/admin/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ko/LC_MESSAGES/django.po +20 -57
- wagtail/admin/locale/lt/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/lt/LC_MESSAGES/django.po +12 -31
- wagtail/admin/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/lv/LC_MESSAGES/django.po +9 -40
- wagtail/admin/locale/mi/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/mi/LC_MESSAGES/django.po +6 -10
- wagtail/admin/locale/mn/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/mn/LC_MESSAGES/django.po +10 -43
- wagtail/admin/locale/my/LC_MESSAGES/django.po +4 -4
- wagtail/admin/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/nb/LC_MESSAGES/django.po +15 -53
- wagtail/admin/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/nl/LC_MESSAGES/django.po +208 -70
- wagtail/admin/locale/nl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/nl/LC_MESSAGES/djangojs.po +19 -2
- wagtail/admin/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pl/LC_MESSAGES/django.po +27 -72
- wagtail/admin/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pt_BR/LC_MESSAGES/django.po +38 -83
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +17 -56
- wagtail/admin/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ro/LC_MESSAGES/django.po +23 -68
- wagtail/admin/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ru/LC_MESSAGES/django.po +96 -84
- wagtail/admin/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sk_SK/LC_MESSAGES/django.po +9 -28
- wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/django.po +45 -90
- wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sv/LC_MESSAGES/django.po +27 -72
- wagtail/admin/locale/tet/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/tet/LC_MESSAGES/django.po +12 -22
- wagtail/admin/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/th/LC_MESSAGES/django.po +10 -42
- wagtail/admin/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/tr/LC_MESSAGES/django.po +64 -70
- wagtail/admin/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/tr_TR/LC_MESSAGES/django.po +15 -42
- wagtail/admin/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ug/LC_MESSAGES/django.po +38 -83
- wagtail/admin/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/uk/LC_MESSAGES/django.po +15 -45
- wagtail/admin/locale/vi/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/vi/LC_MESSAGES/django.po +4 -17
- wagtail/admin/locale/zh/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/zh/LC_MESSAGES/django.po +7 -19
- wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.po +17 -54
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.po +15 -37
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
- wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +2 -2
- wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
- wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
- wagtail/admin/static/wagtailadmin/js/icons.js +1 -1
- wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +2 -2
- wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-transition.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery-3.6.0.min.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery-ui-1.13.2.min.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.datetimepicker.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload-process.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.iframe-transport.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/tag-it.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +1 -1
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/templates/wagtailadmin/account/account.html +2 -0
- wagtail/admin/templates/wagtailadmin/base.html +14 -0
- wagtail/admin/templates/wagtailadmin/generic/chooser/chooser.html +2 -1
- wagtail/admin/templates/wagtailadmin/generic/chooser/creation_form.html +2 -1
- wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
- wagtail/admin/templates/wagtailadmin/panels/object_list.html +1 -1
- wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +3 -2
- wagtail/admin/templates/wagtailadmin/shared/formatted_field.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +19 -0
- wagtail/admin/templates/wagtailadmin/shared/panel.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/set_privacy.html +15 -0
- wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +28 -1
- wagtail/admin/templates/wagtailadmin/shared/workflow_history/detail.html +2 -2
- wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_header.html → tables/ordering_header.html} +2 -2
- wagtail/admin/templates/wagtailadmin/tables/title_cell.html +1 -1
- wagtail/admin/templates/wagtailadmin/widgets/{daterange_input.html → range_input.html} +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/task_chooser/chooser.html +4 -2
- wagtail/admin/templatetags/wagtailadmin_tags.py +41 -22
- wagtail/admin/tests/api/test_pages.py +7 -7
- wagtail/admin/tests/api/test_renderer_classes.py +16 -0
- wagtail/admin/tests/pages/test_create_page.py +42 -2
- wagtail/admin/tests/pages/test_edit_page.py +128 -14
- wagtail/admin/tests/pages/test_explorer_view.py +34 -7
- wagtail/admin/tests/pages/test_reorder_page.py +11 -0
- wagtail/admin/tests/test_collections_views.py +12 -0
- wagtail/admin/tests/test_edit_handlers.py +3 -3
- wagtail/admin/tests/test_filters.py +2 -2
- wagtail/admin/tests/test_keyboard_shortcuts.py +52 -2
- wagtail/admin/tests/test_menu.py +0 -2
- wagtail/admin/tests/test_privacy.py +16 -16
- wagtail/admin/tests/test_templatetags.py +137 -0
- wagtail/admin/tests/test_workflows.py +34 -0
- wagtail/admin/tests/viewsets/test_model_viewset.py +322 -0
- wagtail/admin/ui/tables/orderable.py +73 -0
- wagtail/admin/ui/tables/pages.py +3 -13
- wagtail/admin/views/collection_privacy.py +6 -2
- wagtail/admin/views/generic/__init__.py +1 -0
- wagtail/admin/views/generic/mixins.py +20 -2
- wagtail/admin/views/generic/models.py +67 -1
- wagtail/admin/views/generic/ordering.py +79 -0
- wagtail/admin/views/home.py +3 -3
- wagtail/admin/views/page_privacy.py +5 -2
- wagtail/admin/views/pages/create.py +1 -1
- wagtail/admin/views/pages/edit.py +2 -2
- wagtail/admin/views/pages/listing.py +7 -42
- wagtail/admin/views/pages/move.py +1 -1
- wagtail/admin/views/pages/ordering.py +1 -1
- wagtail/admin/viewsets/base.py +1 -1
- wagtail/admin/viewsets/model.py +49 -1
- wagtail/admin/wagtail_hooks.py +2 -1
- wagtail/admin/widgets/slug.py +10 -10
- wagtail/api/v2/serializers.py +1 -1
- wagtail/api/v2/tests/test_renderer_classes.py +32 -0
- wagtail/apps.py +2 -0
- wagtail/bin/wagtail.py +1 -1
- wagtail/contrib/forms/locale/af/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/be/LC_MESSAGES/django.po +1 -1
- 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.po +1 -1
- wagtail/contrib/forms/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +14 -14
- wagtail/contrib/forms/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/hy/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/lt/LC_MESSAGES/django.po +1 -1
- 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.po +1 -1
- wagtail/contrib/forms/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.po +20 -3
- wagtail/contrib/forms/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.po +19 -2
- wagtail/contrib/forms/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/tr/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/forms/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/forms/locale/uk/LC_MESSAGES/django.po +1 -1
- 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.po +1 -1
- wagtail/contrib/forms/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/frontend_cache/tests.py +4 -2
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +9 -10
- wagtail/contrib/redirects/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/cs/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/de/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +4 -4
- 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 +1 -14
- wagtail/contrib/redirects/locale/es_419/LC_MESSAGES/django.po +1 -1
- 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 +1 -13
- wagtail/contrib/redirects/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/fi/LC_MESSAGES/django.po +7 -11
- wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.po +9 -8
- wagtail/contrib/redirects/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/gl/LC_MESSAGES/django.po +9 -9
- wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.po +1 -1
- 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 +1 -13
- wagtail/contrib/redirects/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/hu/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/hy/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/is_IS/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.po +1 -14
- wagtail/contrib/redirects/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ja/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/nb/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/nl/LC_MESSAGES/django.po +9 -9
- wagtail/contrib/redirects/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/pl/LC_MESSAGES/django.po +1 -14
- wagtail/contrib/redirects/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/pt_BR/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/pt_PT/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ro/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ru/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/sl/LC_MESSAGES/django.po +1 -14
- 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 +1 -13
- wagtail/contrib/redirects/locale/ta/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/tr/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ug/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/uk/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/zh_Hans/LC_MESSAGES/django.po +1 -13
- wagtail/contrib/redirects/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/redirects/tests/test_tmp_storages.py +20 -0
- wagtail/contrib/redirects/tmp_storages.py +1 -1
- wagtail/contrib/redirects/views.py +3 -3
- wagtail/contrib/search_promotions/locale/af/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ar/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/be/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ca/LC_MESSAGES/django.po +5 -5
- wagtail/contrib/search_promotions/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/cs/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/de/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/el/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/el/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/search_promotions/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/es/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/et/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/et/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/fa/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/fi/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.po +5 -5
- wagtail/contrib/search_promotions/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/gl/LC_MESSAGES/django.po +5 -5
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/hu/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/id_ID/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/is_IS/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ja/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ko/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/lt/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/lt/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/lv/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/nb/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/nb/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/nl/LC_MESSAGES/django.po +4 -4
- wagtail/contrib/search_promotions/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/pl/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/pt_BR/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/pt_PT/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ro/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ru/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/sk_SK/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/tet/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/tet/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/th/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.po +44 -10
- wagtail/contrib/search_promotions/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/tr_TR/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/ug/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/uk/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/search_promotions/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/zh_Hans/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/zh_Hant/LC_MESSAGES/django.po +1 -7
- wagtail/contrib/search_promotions/static/wagtailsearchpromotions/js/query-chooser-modal.js +1 -1
- wagtail/contrib/search_promotions/views/settings.py +2 -2
- wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.po +6 -2
- wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/tests/site_specific/test_admin.py +48 -6
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/templates/wagtailstyleguide/base.html +5 -5
- wagtail/contrib/table_block/blocks.py +1 -0
- wagtail/contrib/table_block/locale/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.mo +0 -0
- wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.po +6 -3
- 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 +5 -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.mo +0 -0
- wagtail/contrib/table_block/locale/fr/LC_MESSAGES/django.po +6 -3
- wagtail/contrib/table_block/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/gl/LC_MESSAGES/django.po +6 -3
- 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.mo +0 -0
- wagtail/contrib/table_block/locale/nl/LC_MESSAGES/django.po +6 -3
- 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/table_block/static/table_block/js/table.js +1 -1
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/coreutils.py +5 -5
- wagtail/documents/forms.py +18 -1
- wagtail/documents/locale/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 +1 -5
- wagtail/documents/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/be/LC_MESSAGES/django.po +1 -5
- 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 +5 -5
- wagtail/documents/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/cs/LC_MESSAGES/django.po +1 -7
- 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 +1 -7
- wagtail/documents/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/el/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/el/LC_MESSAGES/django.po +1 -7
- wagtail/documents/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/documents/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/es/LC_MESSAGES/django.po +1 -7
- wagtail/documents/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/et/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/et/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/fa/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/fa/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/fi/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/fr/LC_MESSAGES/django.po +5 -5
- wagtail/documents/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/gl/LC_MESSAGES/django.po +5 -5
- wagtail/documents/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/he_IL/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/hr_HR/LC_MESSAGES/django.po +1 -6
- 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 +1 -7
- wagtail/documents/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/id_ID/LC_MESSAGES/django.po +1 -6
- wagtail/documents/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/is_IS/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/it/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/ja/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ja/LC_MESSAGES/django.po +1 -7
- 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 +1 -6
- wagtail/documents/locale/lt/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/lt/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/mi/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/mi/LC_MESSAGES/django.po +1 -7
- wagtail/documents/locale/mn/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/mn/LC_MESSAGES/django.po +1 -5
- 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 +1 -5
- wagtail/documents/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/nl/LC_MESSAGES/django.po +15 -6
- wagtail/documents/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/pl/LC_MESSAGES/django.po +1 -6
- wagtail/documents/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/pt_BR/LC_MESSAGES/django.po +1 -7
- wagtail/documents/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/pt_PT/LC_MESSAGES/django.po +1 -6
- wagtail/documents/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ro/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ru/LC_MESSAGES/django.po +10 -7
- wagtail/documents/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/sk_SK/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/sl/LC_MESSAGES/django.po +1 -7
- wagtail/documents/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/sv/LC_MESSAGES/django.po +1 -6
- wagtail/documents/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/documents/locale/th/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/th/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/tr/LC_MESSAGES/django.po +13 -5
- wagtail/documents/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/tr_TR/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ug/LC_MESSAGES/django.po +1 -5
- wagtail/documents/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/uk/LC_MESSAGES/django.po +1 -5
- 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 +1 -5
- wagtail/documents/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/zh_Hant/LC_MESSAGES/django.po +1 -5
- wagtail/documents/models.py +1 -1
- wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
- wagtail/documents/templates/wagtaildocs/documents/add.html +0 -34
- wagtail/documents/tests/test_admin_views.py +132 -26
- wagtail/documents/tests/test_collection_privacy.py +18 -4
- wagtail/documents/tests/test_form_overrides.py +1 -1
- wagtail/documents/tests/test_search.py +21 -8
- wagtail/documents/views/documents.py +1 -1
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/static/wagtailembeds/js/embed-chooser-modal.js +1 -1
- wagtail/images/forms.py +16 -1
- wagtail/images/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ar/LC_MESSAGES/django.po +7 -10
- wagtail/images/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/be/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/bg/LC_MESSAGES/django.po +4 -4
- 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 +15 -9
- wagtail/images/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/cs/LC_MESSAGES/django.po +19 -8
- wagtail/images/locale/cy/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/de/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/dv/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/el/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/en/LC_MESSAGES/django.po +57 -46
- wagtail/images/locale/es/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/et/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/fa/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/fi/LC_MESSAGES/django.po +18 -9
- wagtail/images/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/fr/LC_MESSAGES/django.po +15 -9
- wagtail/images/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/gl/LC_MESSAGES/django.po +15 -9
- wagtail/images/locale/he_IL/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/hr_HR/LC_MESSAGES/django.po +7 -7
- 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 +7 -10
- wagtail/images/locale/id_ID/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/is_IS/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/it/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/ja/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/ka/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/ko/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/lt/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/lv/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/mi/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/mn/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/images/locale/nb/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/nl/LC_MESSAGES/django.po +50 -21
- wagtail/images/locale/pl/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/pt_BR/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/ro/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ru/LC_MESSAGES/django.po +24 -8
- wagtail/images/locale/sk_SK/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/sl/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/sv/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/tet/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/th/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/tr/LC_MESSAGES/django.po +85 -7
- wagtail/images/locale/tr_TR/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/ug/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/uk/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/vi/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/zh/LC_MESSAGES/django.po +4 -4
- wagtail/images/locale/zh_Hans/LC_MESSAGES/django.po +7 -7
- wagtail/images/locale/zh_Hant/LC_MESSAGES/django.po +7 -7
- wagtail/images/models.py +1 -1
- wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
- wagtail/images/static/wagtailimages/js/focal-point-chooser.js +1 -1
- wagtail/images/static/wagtailimages/js/image-block.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
- wagtail/images/static/wagtailimages/js/image-url-generator.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.Jcrop.min.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-image.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-validate.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/load-image.min.js +1 -1
- wagtail/images/templates/wagtailimages/chooser/chooser.html +22 -13
- wagtail/images/templates/wagtailimages/chooser/image_preview_column_cell.html +10 -0
- wagtail/images/templates/wagtailimages/chooser/results.html +24 -20
- wagtail/images/templates/wagtailimages/chooser/title_column_cell.html +15 -0
- wagtail/images/templates/wagtailimages/images/add.html +0 -34
- wagtail/images/templates/wagtailimages/images/index.html +3 -3
- wagtail/images/templates/wagtailimages/images/index_results.html +1 -1
- wagtail/images/templates/wagtailimages/images/layout_toggle_button.html +8 -7
- wagtail/images/templatetags/wagtailimages_tags.py +2 -2
- wagtail/images/tests/test_admin_views.py +87 -0
- wagtail/images/tests/test_form_overrides.py +1 -1
- wagtail/images/tests/test_models.py +48 -9
- wagtail/images/views/chooser.py +66 -2
- wagtail/locale/af/LC_MESSAGES/django.po +1 -1
- wagtail/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ar/LC_MESSAGES/django.po +1 -9
- wagtail/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ca/LC_MESSAGES/django.po +4 -4
- wagtail/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/de/LC_MESSAGES/django.po +1 -9
- wagtail/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/dv/LC_MESSAGES/django.po +1 -8
- wagtail/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/locale/en/LC_MESSAGES/django.po +55 -55
- wagtail/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/fr/LC_MESSAGES/django.po +4 -4
- wagtail/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/gl/LC_MESSAGES/django.po +3 -3
- wagtail/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/hu/LC_MESSAGES/django.po +1 -9
- wagtail/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/is_IS/LC_MESSAGES/django.po +4 -12
- wagtail/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/nl/LC_MESSAGES/django.po +15 -6
- wagtail/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/pl/LC_MESSAGES/django.po +1 -9
- wagtail/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ro/LC_MESSAGES/django.po +1 -9
- wagtail/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ru/LC_MESSAGES/django.po +12 -10
- wagtail/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sl/LC_MESSAGES/django.po +1 -9
- wagtail/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sv/LC_MESSAGES/django.po +1 -9
- wagtail/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/tr/LC_MESSAGES/django.po +4 -8
- wagtail/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ug/LC_MESSAGES/django.po +1 -8
- wagtail/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/nl/LC_MESSAGES/django.po +12 -1
- wagtail/locales/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/ru/LC_MESSAGES/django.po +10 -1
- wagtail/locales/views.py +2 -2
- wagtail/models/orderable.py +10 -0
- wagtail/models/pages.py +9 -11
- wagtail/models/sites.py +1 -1
- wagtail/models/workflows.py +8 -5
- wagtail/project_template/home/tests.py +6 -7
- wagtail/project_template/project_name/settings/base.py +9 -9
- wagtail/project_template/requirements.txt +1 -1
- wagtail/query.py +7 -2
- wagtail/rich_text/rewriters.py +1 -1
- wagtail/search/apps.py +4 -49
- wagtail/search/backends/__init__.py +1 -113
- wagtail/search/backends/base.py +1 -547
- wagtail/search/backends/database/__init__.py +1 -50
- wagtail/search/backends/database/fallback.py +1 -253
- wagtail/search/backends/database/mysql/mysql.py +1 -700
- wagtail/search/backends/database/mysql/query.py +1 -258
- wagtail/search/backends/database/postgres/postgres.py +1 -749
- wagtail/search/backends/database/postgres/query.py +1 -83
- wagtail/search/backends/database/postgres/weights.py +1 -63
- wagtail/search/backends/database/sqlite/query.py +1 -294
- wagtail/search/backends/database/sqlite/sqlite.py +1 -719
- wagtail/search/backends/database/sqlite/utils.py +1 -35
- wagtail/search/backends/deprecation.py +45 -0
- wagtail/search/backends/elasticsearch7.py +18 -1260
- wagtail/search/backends/elasticsearch8.py +21 -96
- wagtail/search/backends/elasticsearch9.py +35 -0
- wagtail/search/backends/opensearch2.py +35 -0
- wagtail/search/backends/opensearch3.py +35 -0
- wagtail/search/index.py +1 -358
- wagtail/search/locale/ar/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/ar/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/be/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/be/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/ca/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/cy/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/cy/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/de/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/dv/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/dv/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/en/LC_MESSAGES/django.po +2 -10
- wagtail/search/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/es/LC_MESSAGES/django.po +1 -7
- 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.mo +0 -0
- wagtail/search/locale/fi/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/fr/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/gl/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/gl/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/hr_HR/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/hu/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/is_IS/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/it/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/ko/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/ko/LC_MESSAGES/django.po +1 -7
- 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.mo +0 -0
- wagtail/search/locale/nb/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/nl/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/pl/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/pl/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/pt_BR/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/pt_PT/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/ro/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/ru/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/sl/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/sv/LC_MESSAGES/django.po +1 -7
- 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.mo +0 -0
- wagtail/search/locale/tr/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/ug/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/ug/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/uk/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/uk/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/search/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- wagtail/search/locale/zh_Hans/LC_MESSAGES/django.po +1 -7
- wagtail/search/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/search/management/commands/update_index.py +1 -205
- wagtail/search/management/commands/wagtail_update_index.py +1 -4
- wagtail/search/models.py +29 -158
- wagtail/search/query.py +1 -114
- wagtail/search/queryset.py +1 -43
- wagtail/search/signal_handlers.py +1 -24
- wagtail/search/tasks.py +1 -10
- wagtail/search/tests/test_elasticsearch.py +22 -0
- wagtail/search/utils.py +1 -206
- wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/af/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/az_AZ/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/bn/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/snippets/locale/en_IN/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/es_419/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/es_VE/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/et/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/eu/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/hi/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ht/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ka/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/ru/LC_MESSAGES/django.po +9 -2
- wagtail/snippets/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/sr/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ta/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/tr/LC_MESSAGES/django.po +9 -2
- wagtail/snippets/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/ug/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
- wagtail/snippets/tests/test_reordering.py +319 -0
- wagtail/snippets/tests/test_snippets.py +77 -12
- wagtail/snippets/views/snippets.py +16 -0
- wagtail/test/numberformat.py +30 -0
- wagtail/test/settings.py +35 -12
- wagtail/test/testapp/fields.py +12 -0
- wagtail/test/testapp/migrations/0056_commentablejsonpage.py +50 -0
- wagtail/test/testapp/migrations/0057_featurecompletetoy_sort_order.py +23 -0
- wagtail/test/testapp/migrations/0058_customlocktask.py +31 -0
- wagtail/test/testapp/models.py +27 -0
- wagtail/test/testapp/views.py +3 -1
- wagtail/test/utils/page_tests.py +17 -17
- wagtail/test/utils/template_tests.py +4 -6
- wagtail/test/utils/wagtail_tests.py +1 -2
- wagtail/tests/test_page_model.py +15 -0
- wagtail/{search/tests → tests}/test_page_search.py +29 -2
- wagtail/tests/test_search_fields.py +69 -0
- wagtail/tests/test_tests.py +62 -6
- wagtail/tests/test_workflow.py +25 -1
- wagtail/users/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/be/LC_MESSAGES/django.po +1 -1
- 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.po +1 -1
- wagtail/users/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/cs/LC_MESSAGES/django.po +4 -1
- wagtail/users/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/dv/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/en/LC_MESSAGES/django.po +2 -2
- 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.po +1 -1
- wagtail/users/locale/fi/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/fi/LC_MESSAGES/django.po +6 -3
- wagtail/users/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/he_IL/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/hu/LC_MESSAGES/django.po +1 -1
- 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.po +1 -1
- 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.po +1 -1
- 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.po +1 -1
- wagtail/users/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/nl/LC_MESSAGES/django.po +7 -4
- wagtail/users/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/ru/LC_MESSAGES/django.po +6 -2
- wagtail/users/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/tr/LC_MESSAGES/django.po +79 -5
- 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.po +1 -1
- wagtail/users/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/users/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/users/templates/wagtailusers/users/create.html +2 -0
- wagtail/users/templates/wagtailusers/users/edit.html +2 -0
- wagtail/users/tests/test_admin_views.py +4 -0
- wagtail/users/views/users.py +1 -1
- {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/METADATA +8 -7
- {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/RECORD +1102 -1108
- wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +0 -13
- wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +0 -13
- wagtail/search/tests/__init__.py +0 -0
- wagtail/search/tests/elasticsearch_common_tests.py +0 -251
- wagtail/search/tests/test_backends.py +0 -1215
- wagtail/search/tests/test_db_backend.py +0 -62
- wagtail/search/tests/test_elasticsearch7_backend.py +0 -1452
- wagtail/search/tests/test_elasticsearch8_backend.py +0 -15
- wagtail/search/tests/test_index_functions.py +0 -256
- wagtail/search/tests/test_indexed_class.py +0 -157
- wagtail/search/tests/test_mysql_backend.py +0 -192
- wagtail/search/tests/test_postgres_backend.py +0 -210
- wagtail/search/tests/test_queries.py +0 -332
- wagtail/search/tests/test_related_fields.py +0 -102
- wagtail/search/tests/test_sqlite_backend.py +0 -52
- wagtail/test/search/__init__.py +0 -0
- wagtail/test/search/apps.py +0 -9
- wagtail/test/search/fixtures/search.json +0 -545
- wagtail/test/search/migrations/0001_initial.py +0 -146
- wagtail/test/search/migrations/0002_bookunindexed.py +0 -43
- wagtail/test/search/migrations/0003_book_summary.py +0 -18
- wagtail/test/search/migrations/__init__.py +0 -0
- wagtail/test/search/models.py +0 -137
- /wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_cell.html → tables/ordering_cell.html} +0 -0
- /wagtail/{search/checks.py → checks.py} +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/WHEEL +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/entry_points.txt +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/licenses/LICENSE +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/top_level.txt +0 -0
|
@@ -1,1277 +1,35 @@
|
|
|
1
|
-
import
|
|
2
|
-
from
|
|
3
|
-
|
|
4
|
-
from urllib.parse import urlparse
|
|
5
|
-
|
|
6
|
-
from django.db import DEFAULT_DB_ALIAS, models
|
|
7
|
-
from django.db.models import Subquery
|
|
8
|
-
from django.db.models.sql import Query
|
|
9
|
-
from django.db.models.sql.constants import MULTI, SINGLE
|
|
10
|
-
from django.utils.crypto import get_random_string
|
|
11
|
-
from elasticsearch import VERSION as ELASTICSEARCH_VERSION
|
|
12
|
-
from elasticsearch import Elasticsearch, NotFoundError
|
|
13
|
-
from elasticsearch.helpers import bulk
|
|
14
|
-
|
|
15
|
-
from wagtail.search.backends.base import (
|
|
16
|
-
BaseSearchBackend,
|
|
17
|
-
BaseSearchQueryCompiler,
|
|
18
|
-
BaseSearchResults,
|
|
19
|
-
FilterFieldError,
|
|
20
|
-
get_model_root,
|
|
1
|
+
from modelsearch.backends.elasticsearch7 import * # noqa: F403
|
|
2
|
+
from modelsearch.backends.elasticsearch7 import (
|
|
3
|
+
Elasticsearch7AutocompleteQueryCompiler as _Elasticsearch7AutocompleteQueryCompiler,
|
|
21
4
|
)
|
|
22
|
-
from
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
SearchField,
|
|
28
|
-
class_is_indexed,
|
|
29
|
-
get_indexed_models,
|
|
5
|
+
from modelsearch.backends.elasticsearch7 import (
|
|
6
|
+
Elasticsearch7SearchBackend as _Elasticsearch7SearchBackend,
|
|
7
|
+
)
|
|
8
|
+
from modelsearch.backends.elasticsearch7 import (
|
|
9
|
+
Elasticsearch7SearchQueryCompiler as _Elasticsearch7SearchQueryCompiler,
|
|
30
10
|
)
|
|
31
|
-
from wagtail.search.query import And, Boost, Fuzzy, MatchAll, Not, Or, Phrase, PlainText
|
|
32
|
-
from wagtail.utils.utils import deep_update
|
|
33
|
-
|
|
34
|
-
use_new_elasticsearch_api = ELASTICSEARCH_VERSION >= (7, 15)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class Field:
|
|
38
|
-
def __init__(self, field_name, boost=1):
|
|
39
|
-
self.field_name = field_name
|
|
40
|
-
self.boost = boost
|
|
41
|
-
|
|
42
|
-
@property
|
|
43
|
-
def field_name_with_boost(self):
|
|
44
|
-
if self.boost == 1:
|
|
45
|
-
return self.field_name
|
|
46
|
-
else:
|
|
47
|
-
return f"{self.field_name}^{self.boost}"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
class Elasticsearch7Mapping:
|
|
51
|
-
all_field_name = "_all_text"
|
|
52
|
-
edgengrams_field_name = "_edgengrams"
|
|
53
|
-
|
|
54
|
-
type_map = {
|
|
55
|
-
"AutoField": "integer",
|
|
56
|
-
"SmallAutoField": "integer",
|
|
57
|
-
"BigAutoField": "long",
|
|
58
|
-
"BinaryField": "binary",
|
|
59
|
-
"BooleanField": "boolean",
|
|
60
|
-
"CharField": "string",
|
|
61
|
-
"CommaSeparatedIntegerField": "string",
|
|
62
|
-
"DateField": "date",
|
|
63
|
-
"DateTimeField": "date",
|
|
64
|
-
"DecimalField": "double",
|
|
65
|
-
"FileField": "string",
|
|
66
|
-
"FilePathField": "string",
|
|
67
|
-
"FloatField": "double",
|
|
68
|
-
"IntegerField": "integer",
|
|
69
|
-
"BigIntegerField": "long",
|
|
70
|
-
"IPAddressField": "string",
|
|
71
|
-
"GenericIPAddressField": "string",
|
|
72
|
-
"NullBooleanField": "boolean",
|
|
73
|
-
"PositiveIntegerField": "integer",
|
|
74
|
-
"PositiveSmallIntegerField": "integer",
|
|
75
|
-
"PositiveBigIntegerField": "long",
|
|
76
|
-
"SlugField": "string",
|
|
77
|
-
"SmallIntegerField": "integer",
|
|
78
|
-
"TextField": "string",
|
|
79
|
-
"TimeField": "date",
|
|
80
|
-
"URLField": "string",
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
keyword_type = "keyword"
|
|
84
|
-
text_type = "text"
|
|
85
|
-
edgengram_analyzer_config = {
|
|
86
|
-
"analyzer": "edgengram_analyzer",
|
|
87
|
-
"search_analyzer": "standard",
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
def __init__(self, model):
|
|
91
|
-
self.model = model
|
|
92
|
-
|
|
93
|
-
def get_parent(self):
|
|
94
|
-
for base in self.model.__bases__:
|
|
95
|
-
if issubclass(base, Indexed) and issubclass(base, models.Model):
|
|
96
|
-
return type(self)(base)
|
|
97
|
-
|
|
98
|
-
def get_document_type(self):
|
|
99
|
-
return "doc"
|
|
100
|
-
|
|
101
|
-
def get_field_column_name(self, field):
|
|
102
|
-
# Fields in derived models get prefixed with their model name, fields
|
|
103
|
-
# in the root model don't get prefixed at all
|
|
104
|
-
# This is to prevent mapping clashes in cases where two page types have
|
|
105
|
-
# a field with the same name but a different type.
|
|
106
|
-
root_model = get_model_root(self.model)
|
|
107
|
-
definition_model = field.get_definition_model(self.model)
|
|
108
|
-
|
|
109
|
-
if definition_model != root_model:
|
|
110
|
-
prefix = (
|
|
111
|
-
definition_model._meta.app_label.lower()
|
|
112
|
-
+ "_"
|
|
113
|
-
+ definition_model.__name__.lower()
|
|
114
|
-
+ "__"
|
|
115
|
-
)
|
|
116
|
-
else:
|
|
117
|
-
prefix = ""
|
|
118
|
-
|
|
119
|
-
if isinstance(field, FilterField):
|
|
120
|
-
return prefix + field.get_attname(self.model) + "_filter"
|
|
121
|
-
elif isinstance(field, AutocompleteField):
|
|
122
|
-
return prefix + field.get_attname(self.model) + "_edgengrams"
|
|
123
|
-
elif isinstance(field, SearchField):
|
|
124
|
-
return prefix + field.get_attname(self.model)
|
|
125
|
-
elif isinstance(field, RelatedFields):
|
|
126
|
-
return prefix + field.field_name
|
|
127
|
-
|
|
128
|
-
def get_boost_field_name(self, boost):
|
|
129
|
-
# replace . with _ to avoid issues with . in field names
|
|
130
|
-
boost = str(float(boost)).replace(".", "_")
|
|
131
|
-
return f"{self.all_field_name}_boost_{boost}"
|
|
132
|
-
|
|
133
|
-
def get_content_type(self):
|
|
134
|
-
"""
|
|
135
|
-
Returns the content type as a string for the model.
|
|
136
|
-
|
|
137
|
-
For example: "wagtailcore.Page"
|
|
138
|
-
"myapp.MyModel"
|
|
139
|
-
"""
|
|
140
|
-
return self.model._meta.app_label + "." + self.model.__name__
|
|
141
|
-
|
|
142
|
-
def get_all_content_types(self):
|
|
143
|
-
"""
|
|
144
|
-
Returns all the content type strings that apply to this model.
|
|
145
|
-
This includes the models' content type and all concrete ancestor
|
|
146
|
-
models that inherit from Indexed.
|
|
147
|
-
|
|
148
|
-
For example: ["myapp.MyPageModel", "wagtailcore.Page"]
|
|
149
|
-
["myapp.MyModel"]
|
|
150
|
-
"""
|
|
151
|
-
# Add our content type
|
|
152
|
-
content_types = [self.get_content_type()]
|
|
153
|
-
|
|
154
|
-
# Add all ancestor classes content types as well
|
|
155
|
-
ancestor = self.get_parent()
|
|
156
|
-
while ancestor:
|
|
157
|
-
content_types.append(ancestor.get_content_type())
|
|
158
|
-
ancestor = ancestor.get_parent()
|
|
159
|
-
|
|
160
|
-
return content_types
|
|
161
|
-
|
|
162
|
-
def get_field_mapping(self, field):
|
|
163
|
-
if isinstance(field, RelatedFields):
|
|
164
|
-
mapping = {"type": "nested", "properties": {}}
|
|
165
|
-
nested_model = field.get_field(self.model).related_model
|
|
166
|
-
nested_mapping = type(self)(nested_model)
|
|
167
|
-
|
|
168
|
-
for sub_field in field.fields:
|
|
169
|
-
sub_field_name, sub_field_mapping = nested_mapping.get_field_mapping(
|
|
170
|
-
sub_field
|
|
171
|
-
)
|
|
172
|
-
mapping["properties"][sub_field_name] = sub_field_mapping
|
|
173
|
-
|
|
174
|
-
return self.get_field_column_name(field), mapping
|
|
175
|
-
else:
|
|
176
|
-
mapping = {"type": self.type_map.get(field.get_type(self.model), "string")}
|
|
177
|
-
|
|
178
|
-
if isinstance(field, SearchField):
|
|
179
|
-
if mapping["type"] == "string":
|
|
180
|
-
mapping["type"] = self.text_type
|
|
181
|
-
|
|
182
|
-
if field.boost:
|
|
183
|
-
mapping["boost"] = field.boost
|
|
184
|
-
|
|
185
|
-
mapping["include_in_all"] = True
|
|
186
|
-
|
|
187
|
-
if isinstance(field, AutocompleteField):
|
|
188
|
-
mapping["type"] = self.text_type
|
|
189
|
-
mapping.update(self.edgengram_analyzer_config)
|
|
190
|
-
|
|
191
|
-
elif isinstance(field, FilterField):
|
|
192
|
-
if mapping["type"] == "string":
|
|
193
|
-
mapping["type"] = self.keyword_type
|
|
194
|
-
|
|
195
|
-
if "es_extra" in field.kwargs:
|
|
196
|
-
for key, value in field.kwargs["es_extra"].items():
|
|
197
|
-
mapping[key] = value
|
|
198
|
-
|
|
199
|
-
return self.get_field_column_name(field), mapping
|
|
200
|
-
|
|
201
|
-
def get_mapping(self):
|
|
202
|
-
# Make field list
|
|
203
|
-
fields = {
|
|
204
|
-
"pk": {"type": self.keyword_type, "store": True},
|
|
205
|
-
"content_type": {"type": self.keyword_type},
|
|
206
|
-
self.edgengrams_field_name: {"type": self.text_type},
|
|
207
|
-
}
|
|
208
|
-
fields[self.edgengrams_field_name].update(self.edgengram_analyzer_config)
|
|
209
|
-
|
|
210
|
-
for field in self.model.get_search_fields():
|
|
211
|
-
key, val = self.get_field_mapping(field)
|
|
212
|
-
fields[key] = val
|
|
213
|
-
|
|
214
|
-
# Add _all_text field
|
|
215
|
-
fields[self.all_field_name] = {"type": "text"}
|
|
216
|
-
|
|
217
|
-
unique_boosts = set()
|
|
218
|
-
|
|
219
|
-
# Replace {"include_in_all": true} with {"copy_to": ["_all_text", "_all_text_boost_2"]}
|
|
220
|
-
def replace_include_in_all(properties):
|
|
221
|
-
for field_mapping in properties.values():
|
|
222
|
-
if "include_in_all" in field_mapping:
|
|
223
|
-
if field_mapping["include_in_all"]:
|
|
224
|
-
field_mapping["copy_to"] = self.all_field_name
|
|
225
|
-
|
|
226
|
-
if "boost" in field_mapping:
|
|
227
|
-
# added to unique_boosts to avoid duplicate fields, or cases like 2.0 and 2
|
|
228
|
-
unique_boosts.add(field_mapping["boost"])
|
|
229
|
-
field_mapping["copy_to"] = [
|
|
230
|
-
field_mapping["copy_to"],
|
|
231
|
-
self.get_boost_field_name(field_mapping["boost"]),
|
|
232
|
-
]
|
|
233
|
-
del field_mapping["boost"]
|
|
234
|
-
|
|
235
|
-
del field_mapping["include_in_all"]
|
|
236
|
-
|
|
237
|
-
if field_mapping["type"] == "nested":
|
|
238
|
-
replace_include_in_all(field_mapping["properties"])
|
|
239
|
-
|
|
240
|
-
replace_include_in_all(fields)
|
|
241
|
-
for boost in unique_boosts:
|
|
242
|
-
fields[self.get_boost_field_name(boost)] = {"type": "text"}
|
|
243
|
-
|
|
244
|
-
return {
|
|
245
|
-
"properties": fields,
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
def get_document_id(self, obj):
|
|
249
|
-
return str(obj.pk)
|
|
250
|
-
|
|
251
|
-
def _get_nested_document(self, fields, obj):
|
|
252
|
-
doc = {}
|
|
253
|
-
edgengrams = []
|
|
254
|
-
model = type(obj)
|
|
255
|
-
mapping = type(self)(model)
|
|
256
|
-
|
|
257
|
-
for field in fields:
|
|
258
|
-
value = field.get_value(obj)
|
|
259
|
-
doc[mapping.get_field_column_name(field)] = value
|
|
260
|
-
|
|
261
|
-
# Check if this field should be added into _edgengrams
|
|
262
|
-
if isinstance(field, AutocompleteField):
|
|
263
|
-
edgengrams.append(value)
|
|
264
|
-
|
|
265
|
-
return doc, edgengrams
|
|
266
|
-
|
|
267
|
-
def get_document(self, obj):
|
|
268
|
-
# Build document
|
|
269
|
-
doc = {"pk": str(obj.pk), "content_type": self.get_all_content_types()}
|
|
270
|
-
edgengrams = []
|
|
271
|
-
for field in self.model.get_search_fields():
|
|
272
|
-
value = field.get_value(obj)
|
|
273
|
-
|
|
274
|
-
if isinstance(field, RelatedFields):
|
|
275
|
-
if isinstance(value, (models.Manager, models.QuerySet)):
|
|
276
|
-
nested_docs = []
|
|
277
|
-
|
|
278
|
-
for nested_obj in value.all():
|
|
279
|
-
nested_doc, extra_edgengrams = self._get_nested_document(
|
|
280
|
-
field.fields, nested_obj
|
|
281
|
-
)
|
|
282
|
-
nested_docs.append(nested_doc)
|
|
283
|
-
edgengrams.extend(extra_edgengrams)
|
|
284
|
-
|
|
285
|
-
value = nested_docs
|
|
286
|
-
elif isinstance(value, models.Model):
|
|
287
|
-
value, extra_edgengrams = self._get_nested_document(
|
|
288
|
-
field.fields, value
|
|
289
|
-
)
|
|
290
|
-
edgengrams.extend(extra_edgengrams)
|
|
291
|
-
elif isinstance(field, FilterField):
|
|
292
|
-
if isinstance(value, (models.Manager, models.QuerySet)):
|
|
293
|
-
value = list(value.values_list("pk", flat=True))
|
|
294
|
-
elif isinstance(value, models.Model):
|
|
295
|
-
value = value.pk
|
|
296
|
-
elif isinstance(value, (list, tuple)):
|
|
297
|
-
value = [
|
|
298
|
-
item.pk if isinstance(item, models.Model) else item
|
|
299
|
-
for item in value
|
|
300
|
-
]
|
|
301
|
-
|
|
302
|
-
doc[self.get_field_column_name(field)] = value
|
|
303
|
-
|
|
304
|
-
# Check if this field should be added into _edgengrams
|
|
305
|
-
if isinstance(field, AutocompleteField):
|
|
306
|
-
edgengrams.append(value)
|
|
307
|
-
|
|
308
|
-
# Add partials to document
|
|
309
|
-
doc[self.edgengrams_field_name] = edgengrams
|
|
310
|
-
|
|
311
|
-
return doc
|
|
312
|
-
|
|
313
|
-
def __repr__(self):
|
|
314
|
-
return f"<ElasticsearchMapping: {self.model.__name__}>"
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
class Elasticsearch7Index:
|
|
318
|
-
def __init__(self, backend, name):
|
|
319
|
-
self.backend = backend
|
|
320
|
-
self.es = backend.es
|
|
321
|
-
self.mapping_class = backend.mapping_class
|
|
322
|
-
self.name = name
|
|
323
|
-
|
|
324
|
-
if use_new_elasticsearch_api:
|
|
325
|
-
|
|
326
|
-
def put(self):
|
|
327
|
-
self.es.indices.create(index=self.name, **self.backend.settings)
|
|
328
|
-
|
|
329
|
-
def delete(self):
|
|
330
|
-
try:
|
|
331
|
-
self.es.indices.delete(index=self.name)
|
|
332
|
-
except NotFoundError:
|
|
333
|
-
pass
|
|
334
|
-
|
|
335
|
-
def refresh(self):
|
|
336
|
-
self.es.indices.refresh(index=self.name)
|
|
337
|
-
|
|
338
|
-
else:
|
|
339
|
-
|
|
340
|
-
def put(self):
|
|
341
|
-
self.es.indices.create(self.name, self.backend.settings)
|
|
342
|
-
|
|
343
|
-
def delete(self):
|
|
344
|
-
try:
|
|
345
|
-
self.es.indices.delete(self.name)
|
|
346
|
-
except NotFoundError:
|
|
347
|
-
pass
|
|
348
|
-
|
|
349
|
-
def refresh(self):
|
|
350
|
-
self.es.indices.refresh(self.name)
|
|
351
|
-
|
|
352
|
-
def exists(self):
|
|
353
|
-
return self.es.indices.exists(self.name)
|
|
354
|
-
|
|
355
|
-
def is_alias(self):
|
|
356
|
-
return self.es.indices.exists_alias(name=self.name)
|
|
357
|
-
|
|
358
|
-
def aliased_indices(self):
|
|
359
|
-
"""
|
|
360
|
-
If this index object represents an alias (which appear the same in the
|
|
361
|
-
Elasticsearch API), this method can be used to fetch the list of indices
|
|
362
|
-
the alias points to.
|
|
363
|
-
|
|
364
|
-
Use the is_alias method if you need to find out if this an alias. This
|
|
365
|
-
returns an empty list if called on an index.
|
|
366
|
-
"""
|
|
367
|
-
return [
|
|
368
|
-
self.backend.index_class(self.backend, index_name)
|
|
369
|
-
for index_name in self.es.indices.get_alias(name=self.name).keys()
|
|
370
|
-
]
|
|
371
|
-
|
|
372
|
-
def put_alias(self, name):
|
|
373
|
-
"""
|
|
374
|
-
Creates a new alias to this index. If the alias already exists it will
|
|
375
|
-
be repointed to this index.
|
|
376
|
-
"""
|
|
377
|
-
self.es.indices.put_alias(name=name, index=self.name)
|
|
378
|
-
|
|
379
|
-
def add_model(self, model):
|
|
380
|
-
# Get mapping
|
|
381
|
-
mapping = self.mapping_class(model)
|
|
382
|
-
|
|
383
|
-
# Put mapping
|
|
384
|
-
self.es.indices.put_mapping(index=self.name, body=mapping.get_mapping())
|
|
385
|
-
|
|
386
|
-
if use_new_elasticsearch_api:
|
|
387
|
-
|
|
388
|
-
def add_item(self, item):
|
|
389
|
-
# Make sure the object can be indexed
|
|
390
|
-
if not class_is_indexed(item.__class__):
|
|
391
|
-
return
|
|
392
|
-
|
|
393
|
-
# Get mapping
|
|
394
|
-
mapping = self.mapping_class(item.__class__)
|
|
395
|
-
|
|
396
|
-
# Add document to index
|
|
397
|
-
self.es.index(
|
|
398
|
-
index=self.name,
|
|
399
|
-
document=mapping.get_document(item),
|
|
400
|
-
id=mapping.get_document_id(item),
|
|
401
|
-
)
|
|
402
|
-
|
|
403
|
-
else:
|
|
404
|
-
|
|
405
|
-
def add_item(self, item):
|
|
406
|
-
# Make sure the object can be indexed
|
|
407
|
-
if not class_is_indexed(item.__class__):
|
|
408
|
-
return
|
|
409
|
-
# Get mapping
|
|
410
|
-
mapping = self.mapping_class(item.__class__)
|
|
411
|
-
|
|
412
|
-
# Add document to index
|
|
413
|
-
self.es.index(
|
|
414
|
-
self.name, mapping.get_document(item), id=mapping.get_document_id(item)
|
|
415
|
-
)
|
|
416
|
-
|
|
417
|
-
def add_items(self, model, items):
|
|
418
|
-
if not class_is_indexed(model):
|
|
419
|
-
return
|
|
420
|
-
|
|
421
|
-
# Get mapping
|
|
422
|
-
mapping = self.mapping_class(model)
|
|
423
|
-
|
|
424
|
-
# Create list of actions
|
|
425
|
-
actions = []
|
|
426
|
-
for item in items:
|
|
427
|
-
# Create the action
|
|
428
|
-
action = {"_id": mapping.get_document_id(item)}
|
|
429
|
-
action.update(mapping.get_document(item))
|
|
430
|
-
actions.append(action)
|
|
431
|
-
|
|
432
|
-
# Run the actions
|
|
433
|
-
bulk(self.es, actions, index=self.name)
|
|
434
|
-
|
|
435
|
-
def delete_item(self, item):
|
|
436
|
-
# Make sure the object can be indexed
|
|
437
|
-
if not class_is_indexed(item.__class__):
|
|
438
|
-
return
|
|
439
|
-
|
|
440
|
-
# Get mapping
|
|
441
|
-
mapping = self.mapping_class(item.__class__)
|
|
442
|
-
|
|
443
|
-
# Delete document
|
|
444
|
-
try:
|
|
445
|
-
self.es.delete(index=self.name, id=mapping.get_document_id(item))
|
|
446
|
-
except NotFoundError:
|
|
447
|
-
pass # Document doesn't exist, ignore this exception
|
|
448
|
-
|
|
449
|
-
def reset(self):
|
|
450
|
-
# Delete old index
|
|
451
|
-
self.delete()
|
|
452
|
-
|
|
453
|
-
# Create new index
|
|
454
|
-
self.put()
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
class Elasticsearch7SearchQueryCompiler(BaseSearchQueryCompiler):
|
|
458
|
-
mapping_class = Elasticsearch7Mapping
|
|
459
|
-
DEFAULT_OPERATOR = "or"
|
|
460
|
-
|
|
461
|
-
def __init__(self, *args, **kwargs):
|
|
462
|
-
super().__init__(*args, **kwargs)
|
|
463
|
-
self.mapping = self.mapping_class(self.queryset.model)
|
|
464
|
-
self.remapped_fields = self._remap_fields(self.fields)
|
|
465
|
-
|
|
466
|
-
def _remap_fields(self, fields):
|
|
467
|
-
"""Convert field names into index column names and add boosts."""
|
|
468
|
-
|
|
469
|
-
remapped_fields = []
|
|
470
|
-
if fields:
|
|
471
|
-
searchable_fields = {f.field_name: f for f in self.get_searchable_fields()}
|
|
472
|
-
for field_name in fields:
|
|
473
|
-
field = searchable_fields.get(field_name)
|
|
474
|
-
if field:
|
|
475
|
-
field_name = self.mapping.get_field_column_name(field)
|
|
476
|
-
remapped_fields.append(Field(field_name, field.boost or 1))
|
|
477
|
-
else:
|
|
478
|
-
remapped_fields.append(Field(self.mapping.all_field_name))
|
|
479
|
-
|
|
480
|
-
models = get_indexed_models()
|
|
481
|
-
unique_boosts = set()
|
|
482
|
-
for model in models:
|
|
483
|
-
if not issubclass(model, self.queryset.model):
|
|
484
|
-
continue
|
|
485
|
-
for field in model.get_searchable_search_fields():
|
|
486
|
-
if field.boost:
|
|
487
|
-
unique_boosts.add(float(field.boost))
|
|
488
|
-
|
|
489
|
-
remapped_fields.extend(
|
|
490
|
-
[
|
|
491
|
-
Field(self.mapping.get_boost_field_name(boost), boost)
|
|
492
|
-
for boost in unique_boosts
|
|
493
|
-
]
|
|
494
|
-
)
|
|
495
|
-
|
|
496
|
-
return remapped_fields
|
|
497
|
-
|
|
498
|
-
def _process_lookup(self, field, lookup, value):
|
|
499
|
-
column_name = self.mapping.get_field_column_name(field)
|
|
500
|
-
|
|
501
|
-
if lookup == "exact":
|
|
502
|
-
if value is None:
|
|
503
|
-
return {
|
|
504
|
-
"missing": {
|
|
505
|
-
"field": column_name,
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
else:
|
|
509
|
-
if isinstance(value, (Query, Subquery)):
|
|
510
|
-
db_alias = self.queryset._db or DEFAULT_DB_ALIAS
|
|
511
|
-
query = value.query if isinstance(value, Subquery) else value
|
|
512
|
-
value = query.get_compiler(db_alias).execute_sql(result_type=SINGLE)
|
|
513
|
-
# The result is either a tuple with one element or None
|
|
514
|
-
if value:
|
|
515
|
-
value = value[0]
|
|
516
|
-
|
|
517
|
-
return {
|
|
518
|
-
"term": {
|
|
519
|
-
column_name: value,
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
if lookup == "isnull":
|
|
524
|
-
query = {
|
|
525
|
-
"exists": {
|
|
526
|
-
"field": column_name,
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
if value:
|
|
531
|
-
query = {"bool": {"mustNot": query}}
|
|
532
|
-
|
|
533
|
-
return query
|
|
534
|
-
|
|
535
|
-
if lookup in ["startswith", "prefix"]:
|
|
536
|
-
return {
|
|
537
|
-
"prefix": {
|
|
538
|
-
column_name: value,
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
if lookup in ["gt", "gte", "lt", "lte"]:
|
|
543
|
-
return {
|
|
544
|
-
"range": {
|
|
545
|
-
column_name: {
|
|
546
|
-
lookup: value,
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
if lookup == "range":
|
|
552
|
-
lower, upper = value
|
|
553
|
-
|
|
554
|
-
return {
|
|
555
|
-
"range": {
|
|
556
|
-
column_name: {
|
|
557
|
-
"gte": lower,
|
|
558
|
-
"lte": upper,
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
if lookup == "in":
|
|
564
|
-
if isinstance(value, (Query, Subquery)):
|
|
565
|
-
db_alias = self.queryset._db or DEFAULT_DB_ALIAS
|
|
566
|
-
query = value.query if isinstance(value, Subquery) else value
|
|
567
|
-
resultset = query.get_compiler(db_alias).execute_sql(result_type=MULTI)
|
|
568
|
-
value = [row[0] for chunk in resultset for row in chunk]
|
|
569
|
-
|
|
570
|
-
elif not isinstance(value, list):
|
|
571
|
-
value = list(value)
|
|
572
|
-
return {
|
|
573
|
-
"terms": {
|
|
574
|
-
column_name: value,
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
def _process_match_none(self):
|
|
579
|
-
return {"bool": {"mustNot": {"match_all": {}}}}
|
|
580
|
-
|
|
581
|
-
def _connect_filters(self, filters, connector, negated):
|
|
582
|
-
if filters:
|
|
583
|
-
if len(filters) == 1:
|
|
584
|
-
filter_out = filters[0]
|
|
585
|
-
elif connector == "AND":
|
|
586
|
-
filter_out = {
|
|
587
|
-
"bool": {"must": [fil for fil in filters if fil is not None]}
|
|
588
|
-
}
|
|
589
|
-
elif connector == "OR":
|
|
590
|
-
filter_out = {
|
|
591
|
-
"bool": {"should": [fil for fil in filters if fil is not None]}
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
if negated:
|
|
595
|
-
filter_out = {"bool": {"mustNot": filter_out}}
|
|
596
|
-
|
|
597
|
-
return filter_out
|
|
598
|
-
|
|
599
|
-
def _compile_plaintext_query(self, query, fields, boost=1.0):
|
|
600
|
-
match_query = {"query": query.query_string}
|
|
601
|
-
|
|
602
|
-
if query.operator != "or":
|
|
603
|
-
match_query["operator"] = query.operator
|
|
604
|
-
|
|
605
|
-
if len(fields) == 1:
|
|
606
|
-
if boost != 1.0 or fields[0].boost != 1.0:
|
|
607
|
-
match_query["boost"] = boost * fields[0].boost
|
|
608
|
-
return {"match": {fields[0].field_name: match_query}}
|
|
609
|
-
else:
|
|
610
|
-
if boost != 1.0:
|
|
611
|
-
match_query["boost"] = boost
|
|
612
|
-
match_query["fields"] = [field.field_name_with_boost for field in fields]
|
|
613
|
-
|
|
614
|
-
return {"multi_match": match_query}
|
|
615
|
-
|
|
616
|
-
def _compile_fuzzy_query(self, query, fields):
|
|
617
|
-
match_query = {
|
|
618
|
-
"query": query.query_string,
|
|
619
|
-
"fuzziness": "AUTO",
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
if query.operator != "or":
|
|
623
|
-
match_query["operator"] = query.operator
|
|
624
|
-
|
|
625
|
-
if len(fields) == 1:
|
|
626
|
-
if fields[0].boost != 1.0:
|
|
627
|
-
match_query["boost"] = fields[0].boost
|
|
628
|
-
return {"match": {fields[0].field_name: match_query}}
|
|
629
|
-
else:
|
|
630
|
-
match_query["fields"] = [field.field_name_with_boost for field in fields]
|
|
631
|
-
return {"multi_match": match_query}
|
|
632
|
-
|
|
633
|
-
def _compile_phrase_query(self, query, fields):
|
|
634
|
-
if len(fields) == 1:
|
|
635
|
-
if fields[0].boost != 1.0:
|
|
636
|
-
return {
|
|
637
|
-
"match_phrase": {
|
|
638
|
-
fields[0].field_name: {
|
|
639
|
-
"query": query.query_string,
|
|
640
|
-
"boost": fields[0].boost,
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
else:
|
|
645
|
-
return {"match_phrase": {fields[0].field_name: query.query_string}}
|
|
646
|
-
else:
|
|
647
|
-
return {
|
|
648
|
-
"multi_match": {
|
|
649
|
-
"query": query.query_string,
|
|
650
|
-
"fields": [field.field_name_with_boost for field in fields],
|
|
651
|
-
"type": "phrase",
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
def _compile_query(self, query, field, boost=1.0):
|
|
656
|
-
if isinstance(query, MatchAll):
|
|
657
|
-
match_all_query = {}
|
|
658
|
-
|
|
659
|
-
if boost != 1.0:
|
|
660
|
-
match_all_query["boost"] = boost
|
|
661
|
-
|
|
662
|
-
return {"match_all": match_all_query}
|
|
663
|
-
|
|
664
|
-
elif isinstance(query, And):
|
|
665
|
-
return {
|
|
666
|
-
"bool": {
|
|
667
|
-
"must": [
|
|
668
|
-
self._compile_query(child_query, field, boost)
|
|
669
|
-
for child_query in query.subqueries
|
|
670
|
-
]
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
elif isinstance(query, Or):
|
|
675
|
-
return {
|
|
676
|
-
"bool": {
|
|
677
|
-
"should": [
|
|
678
|
-
self._compile_query(child_query, field, boost)
|
|
679
|
-
for child_query in query.subqueries
|
|
680
|
-
]
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
elif isinstance(query, Not):
|
|
685
|
-
return {
|
|
686
|
-
"bool": {"mustNot": self._compile_query(query.subquery, field, boost)}
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
elif isinstance(query, PlainText):
|
|
690
|
-
return self._compile_plaintext_query(query, [field], boost)
|
|
691
|
-
|
|
692
|
-
elif isinstance(query, Fuzzy):
|
|
693
|
-
return self._compile_fuzzy_query(query, [field])
|
|
694
|
-
|
|
695
|
-
elif isinstance(query, Phrase):
|
|
696
|
-
return self._compile_phrase_query(query, [field])
|
|
697
|
-
|
|
698
|
-
elif isinstance(query, Boost):
|
|
699
|
-
return self._compile_query(query.subquery, field, boost * query.boost)
|
|
700
|
-
|
|
701
|
-
else:
|
|
702
|
-
raise NotImplementedError(
|
|
703
|
-
"`%s` is not supported by the Elasticsearch search backend."
|
|
704
|
-
% query.__class__.__name__
|
|
705
|
-
)
|
|
706
|
-
|
|
707
|
-
def get_inner_query(self):
|
|
708
|
-
if self.remapped_fields:
|
|
709
|
-
fields = self.remapped_fields
|
|
710
|
-
else:
|
|
711
|
-
fields = [self.mapping.all_field_name]
|
|
712
|
-
|
|
713
|
-
if len(fields) == 0:
|
|
714
|
-
# No fields. Return a query that'll match nothing
|
|
715
|
-
return {"bool": {"mustNot": {"match_all": {}}}}
|
|
716
|
-
|
|
717
|
-
# Handle MatchAll and PlainText separately as they were supported
|
|
718
|
-
# before "search query classes" was implemented and we'd like to
|
|
719
|
-
# keep the query the same as before
|
|
720
|
-
if isinstance(self.query, MatchAll):
|
|
721
|
-
return {"match_all": {}}
|
|
722
|
-
|
|
723
|
-
elif isinstance(self.query, PlainText):
|
|
724
|
-
return self._compile_plaintext_query(self.query, fields)
|
|
725
|
-
|
|
726
|
-
elif isinstance(self.query, Phrase):
|
|
727
|
-
return self._compile_phrase_query(self.query, fields)
|
|
728
|
-
|
|
729
|
-
elif isinstance(self.query, Fuzzy):
|
|
730
|
-
return self._compile_fuzzy_query(self.query, fields)
|
|
731
|
-
|
|
732
|
-
elif isinstance(self.query, Not):
|
|
733
|
-
return {
|
|
734
|
-
"bool": {
|
|
735
|
-
"mustNot": [
|
|
736
|
-
self._compile_query(self.query.subquery, field)
|
|
737
|
-
for field in fields
|
|
738
|
-
]
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
else:
|
|
743
|
-
return self._join_and_compile_queries(self.query, fields)
|
|
744
|
-
|
|
745
|
-
def _join_and_compile_queries(self, query, fields, boost=1.0):
|
|
746
|
-
if len(fields) == 1:
|
|
747
|
-
return self._compile_query(query, fields[0], boost)
|
|
748
|
-
else:
|
|
749
|
-
# Compile a query for each field then combine with disjunction
|
|
750
|
-
# max (or operator which takes the max score out of each of the
|
|
751
|
-
# field queries)
|
|
752
|
-
field_queries = []
|
|
753
|
-
for field in fields:
|
|
754
|
-
field_queries.append(self._compile_query(query, field, boost))
|
|
755
|
-
|
|
756
|
-
return {"dis_max": {"queries": field_queries}}
|
|
757
|
-
|
|
758
|
-
def get_content_type_filter(self):
|
|
759
|
-
# Query content_type using a "match" query. See comment in
|
|
760
|
-
# Elasticsearch7Mapping.get_document for more details
|
|
761
|
-
content_type = self.mapping_class(self.queryset.model).get_content_type()
|
|
762
|
-
|
|
763
|
-
return {"match": {"content_type": content_type}}
|
|
764
|
-
|
|
765
|
-
def get_filters(self):
|
|
766
|
-
# Filter by content type
|
|
767
|
-
filters = [self.get_content_type_filter()]
|
|
768
|
-
|
|
769
|
-
# Apply filters from queryset
|
|
770
|
-
queryset_filters = self._get_filters_from_queryset()
|
|
771
|
-
if queryset_filters:
|
|
772
|
-
filters.append(queryset_filters)
|
|
773
|
-
|
|
774
|
-
return filters
|
|
775
|
-
|
|
776
|
-
def get_query(self):
|
|
777
|
-
inner_query = self.get_inner_query()
|
|
778
|
-
filters = self.get_filters()
|
|
779
|
-
|
|
780
|
-
if len(filters) == 1:
|
|
781
|
-
return {
|
|
782
|
-
"bool": {
|
|
783
|
-
"must": inner_query,
|
|
784
|
-
"filter": filters[0],
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
elif len(filters) > 1:
|
|
788
|
-
return {
|
|
789
|
-
"bool": {
|
|
790
|
-
"must": inner_query,
|
|
791
|
-
"filter": filters,
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
else:
|
|
795
|
-
return inner_query
|
|
796
|
-
|
|
797
|
-
def get_searchable_fields(self):
|
|
798
|
-
return self.queryset.model.get_searchable_search_fields()
|
|
799
|
-
|
|
800
|
-
def get_sort(self):
|
|
801
|
-
# Ordering by relevance is the default in Elasticsearch
|
|
802
|
-
if self.order_by_relevance:
|
|
803
|
-
return
|
|
804
|
-
|
|
805
|
-
# Get queryset and make sure its ordered
|
|
806
|
-
if self.queryset.ordered:
|
|
807
|
-
sort = []
|
|
808
|
-
|
|
809
|
-
for reverse, field in self._get_order_by():
|
|
810
|
-
column_name = self.mapping.get_field_column_name(field)
|
|
811
|
-
|
|
812
|
-
sort.append({column_name: "desc" if reverse else "asc"})
|
|
813
|
-
|
|
814
|
-
return sort
|
|
815
|
-
|
|
816
|
-
else:
|
|
817
|
-
# Order by pk field
|
|
818
|
-
return ["pk"]
|
|
819
|
-
|
|
820
|
-
def __repr__(self):
|
|
821
|
-
return json.dumps(self.get_query())
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
class Elasticsearch7SearchResults(BaseSearchResults):
|
|
825
|
-
fields_param_name = "stored_fields"
|
|
826
|
-
supports_facet = True
|
|
827
|
-
|
|
828
|
-
def facet(self, field_name):
|
|
829
|
-
# Get field
|
|
830
|
-
field = self.query_compiler._get_filterable_field(field_name)
|
|
831
|
-
if field is None:
|
|
832
|
-
raise FilterFieldError(
|
|
833
|
-
'Cannot facet search results with field "'
|
|
834
|
-
+ field_name
|
|
835
|
-
+ "\". Please add index.FilterField('"
|
|
836
|
-
+ field_name
|
|
837
|
-
+ "') to "
|
|
838
|
-
+ self.query_compiler.queryset.model.__name__
|
|
839
|
-
+ ".search_fields.",
|
|
840
|
-
field_name=field_name,
|
|
841
|
-
)
|
|
842
|
-
|
|
843
|
-
# Build body
|
|
844
|
-
body = self._get_es_body()
|
|
845
|
-
column_name = self.query_compiler.mapping.get_field_column_name(field)
|
|
846
|
-
|
|
847
|
-
body["aggregations"] = {
|
|
848
|
-
field_name: {
|
|
849
|
-
"terms": {
|
|
850
|
-
"field": column_name,
|
|
851
|
-
"missing": 0,
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
# Send to Elasticsearch
|
|
857
|
-
response = self._backend_do_search(
|
|
858
|
-
body,
|
|
859
|
-
index=self.backend.get_index_for_model(
|
|
860
|
-
self.query_compiler.queryset.model
|
|
861
|
-
).name,
|
|
862
|
-
size=0,
|
|
863
|
-
)
|
|
864
|
-
|
|
865
|
-
return OrderedDict(
|
|
866
|
-
[
|
|
867
|
-
(bucket["key"] if bucket["key"] != 0 else None, bucket["doc_count"])
|
|
868
|
-
for bucket in response["aggregations"][field_name]["buckets"]
|
|
869
|
-
]
|
|
870
|
-
)
|
|
871
|
-
|
|
872
|
-
def _get_es_body(self, for_count=False):
|
|
873
|
-
body = {"query": self.query_compiler.get_query()}
|
|
874
|
-
|
|
875
|
-
if not for_count:
|
|
876
|
-
sort = self.query_compiler.get_sort()
|
|
877
|
-
|
|
878
|
-
if sort is not None:
|
|
879
|
-
body["sort"] = sort
|
|
880
|
-
|
|
881
|
-
return body
|
|
882
|
-
|
|
883
|
-
def _get_results_from_hits(self, hits):
|
|
884
|
-
"""
|
|
885
|
-
Yields Django model instances from a page of hits returned by Elasticsearch
|
|
886
|
-
"""
|
|
887
|
-
# Get pks from results
|
|
888
|
-
pks = [hit["fields"]["pk"][0] for hit in hits]
|
|
889
|
-
scores = {str(hit["fields"]["pk"][0]): hit["_score"] for hit in hits}
|
|
890
|
-
|
|
891
|
-
# Initialise results dictionary
|
|
892
|
-
results = {str(pk): None for pk in pks}
|
|
893
|
-
|
|
894
|
-
# Find objects in database and add them to dict
|
|
895
|
-
for obj in self.query_compiler.queryset.filter(pk__in=pks):
|
|
896
|
-
results[str(obj.pk)] = obj
|
|
897
|
-
|
|
898
|
-
if self._score_field:
|
|
899
|
-
setattr(obj, self._score_field, scores.get(str(obj.pk)))
|
|
900
|
-
|
|
901
|
-
# Yield results in order given by Elasticsearch
|
|
902
|
-
for pk in pks:
|
|
903
|
-
result = results[str(pk)]
|
|
904
|
-
if result:
|
|
905
|
-
yield result
|
|
906
|
-
|
|
907
|
-
if use_new_elasticsearch_api:
|
|
908
|
-
|
|
909
|
-
def _backend_do_search(self, body, **kwargs):
|
|
910
|
-
# As of Elasticsearch 7.15, the 'body' parameter is deprecated; instead, the top-level
|
|
911
|
-
# keys of the body dict are now kwargs in their own right
|
|
912
|
-
return self.backend.es.search(**body, **kwargs)
|
|
913
|
-
|
|
914
|
-
else:
|
|
915
|
-
|
|
916
|
-
def _backend_do_search(self, body, **kwargs):
|
|
917
|
-
# Send the search query to the backend.
|
|
918
|
-
return self.backend.es.search(body=body, **kwargs)
|
|
919
|
-
|
|
920
|
-
def _do_search(self):
|
|
921
|
-
PAGE_SIZE = 100
|
|
922
|
-
|
|
923
|
-
if self.stop is not None:
|
|
924
|
-
limit = self.stop - self.start
|
|
925
|
-
else:
|
|
926
|
-
limit = None
|
|
927
|
-
|
|
928
|
-
use_scroll = limit is None or limit > PAGE_SIZE
|
|
929
|
-
|
|
930
|
-
body = self._get_es_body()
|
|
931
|
-
params = {
|
|
932
|
-
"index": self.backend.get_index_for_model(
|
|
933
|
-
self.query_compiler.queryset.model
|
|
934
|
-
).name,
|
|
935
|
-
"_source": False,
|
|
936
|
-
self.fields_param_name: "pk",
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
if use_scroll:
|
|
940
|
-
params.update(
|
|
941
|
-
{
|
|
942
|
-
"scroll": "2m",
|
|
943
|
-
"size": PAGE_SIZE,
|
|
944
|
-
}
|
|
945
|
-
)
|
|
946
|
-
|
|
947
|
-
# The scroll API doesn't support offset, manually skip the first results
|
|
948
|
-
skip = self.start
|
|
949
|
-
|
|
950
|
-
# Send to Elasticsearch
|
|
951
|
-
page = self._backend_do_search(body, **params)
|
|
952
|
-
|
|
953
|
-
while True:
|
|
954
|
-
hits = page["hits"]["hits"]
|
|
955
|
-
|
|
956
|
-
if len(hits) == 0:
|
|
957
|
-
break
|
|
958
|
-
|
|
959
|
-
# Get results
|
|
960
|
-
if skip < len(hits):
|
|
961
|
-
for result in self._get_results_from_hits(hits):
|
|
962
|
-
if limit is not None and limit == 0:
|
|
963
|
-
break
|
|
964
|
-
|
|
965
|
-
if skip == 0:
|
|
966
|
-
yield result
|
|
967
|
-
|
|
968
|
-
if limit is not None:
|
|
969
|
-
limit -= 1
|
|
970
|
-
else:
|
|
971
|
-
skip -= 1
|
|
972
|
-
|
|
973
|
-
if limit is not None and limit == 0:
|
|
974
|
-
break
|
|
975
|
-
else:
|
|
976
|
-
# Skip whole page
|
|
977
|
-
skip -= len(hits)
|
|
978
|
-
|
|
979
|
-
# Fetch next page of results
|
|
980
|
-
if "_scroll_id" not in page:
|
|
981
|
-
break
|
|
982
|
-
|
|
983
|
-
page = self.backend.es.scroll(scroll_id=page["_scroll_id"], scroll="2m")
|
|
984
|
-
|
|
985
|
-
# Clear the scroll
|
|
986
|
-
if "_scroll_id" in page:
|
|
987
|
-
self.backend.es.clear_scroll(scroll_id=page["_scroll_id"])
|
|
988
|
-
else:
|
|
989
|
-
params.update(
|
|
990
|
-
{
|
|
991
|
-
"from_": self.start,
|
|
992
|
-
"size": limit or PAGE_SIZE,
|
|
993
|
-
}
|
|
994
|
-
)
|
|
995
|
-
|
|
996
|
-
# Send to Elasticsearch
|
|
997
|
-
hits = self._backend_do_search(body, **params)["hits"]["hits"]
|
|
998
|
-
|
|
999
|
-
# Get results
|
|
1000
|
-
for result in self._get_results_from_hits(hits):
|
|
1001
|
-
yield result
|
|
1002
|
-
|
|
1003
|
-
def _do_count(self):
|
|
1004
|
-
# Get count
|
|
1005
|
-
hit_count = self.backend.es.count(
|
|
1006
|
-
index=self.backend.get_index_for_model(
|
|
1007
|
-
self.query_compiler.queryset.model
|
|
1008
|
-
).name,
|
|
1009
|
-
body=self._get_es_body(for_count=True),
|
|
1010
|
-
)["count"]
|
|
1011
|
-
|
|
1012
|
-
# Add limits
|
|
1013
|
-
hit_count -= self.start
|
|
1014
|
-
if self.stop is not None:
|
|
1015
|
-
hit_count = min(hit_count, self.stop - self.start)
|
|
1016
|
-
|
|
1017
|
-
return max(hit_count, 0)
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
class ElasticsearchAutocompleteQueryCompilerImpl:
|
|
1021
|
-
def __init__(self, *args, **kwargs):
|
|
1022
|
-
super().__init__(*args, **kwargs)
|
|
1023
|
-
|
|
1024
|
-
# Convert field names into index column names
|
|
1025
|
-
# Note: this overrides Elasticsearch7SearchQueryCompiler by using autocomplete fields instead of searchable fields
|
|
1026
|
-
if self.fields:
|
|
1027
|
-
fields = []
|
|
1028
|
-
autocomplete_fields = {
|
|
1029
|
-
f.field_name: f
|
|
1030
|
-
for f in self.queryset.model.get_autocomplete_search_fields()
|
|
1031
|
-
}
|
|
1032
|
-
for field_name in self.fields:
|
|
1033
|
-
if field_name in autocomplete_fields:
|
|
1034
|
-
field_name = self.mapping.get_field_column_name(
|
|
1035
|
-
autocomplete_fields[field_name]
|
|
1036
|
-
)
|
|
1037
11
|
|
|
1038
|
-
|
|
12
|
+
from wagtail.search.backends.deprecation import (
|
|
13
|
+
IndexOptionMixin,
|
|
14
|
+
LegacyContentTypeMatchMixin,
|
|
15
|
+
)
|
|
1039
16
|
|
|
1040
|
-
self.remapped_fields = fields
|
|
1041
|
-
else:
|
|
1042
|
-
self.remapped_fields = None
|
|
1043
17
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
# No fields. Return a query that'll match nothing
|
|
1049
|
-
return {"bool": {"mustNot": {"match_all": {}}}}
|
|
1050
|
-
elif isinstance(self.query, PlainText):
|
|
1051
|
-
return self._compile_plaintext_query(self.query, fields)
|
|
1052
|
-
elif isinstance(self.query, MatchAll):
|
|
1053
|
-
return {"match_all": {}}
|
|
1054
|
-
else:
|
|
1055
|
-
raise NotImplementedError(
|
|
1056
|
-
"`%s` is not supported for autocomplete queries."
|
|
1057
|
-
% self.query.__class__.__name__
|
|
1058
|
-
)
|
|
18
|
+
class Elasticsearch7SearchQueryCompiler(
|
|
19
|
+
LegacyContentTypeMatchMixin, _Elasticsearch7SearchQueryCompiler
|
|
20
|
+
):
|
|
21
|
+
pass
|
|
1059
22
|
|
|
1060
23
|
|
|
1061
24
|
class Elasticsearch7AutocompleteQueryCompiler(
|
|
1062
|
-
|
|
25
|
+
LegacyContentTypeMatchMixin, _Elasticsearch7AutocompleteQueryCompiler
|
|
1063
26
|
):
|
|
1064
27
|
pass
|
|
1065
28
|
|
|
1066
29
|
|
|
1067
|
-
class
|
|
1068
|
-
def __init__(self, index):
|
|
1069
|
-
self.index = index
|
|
1070
|
-
|
|
1071
|
-
def reset_index(self):
|
|
1072
|
-
self.index.reset()
|
|
1073
|
-
|
|
1074
|
-
def start(self):
|
|
1075
|
-
# Reset the index
|
|
1076
|
-
self.reset_index()
|
|
1077
|
-
|
|
1078
|
-
return self.index
|
|
1079
|
-
|
|
1080
|
-
def finish(self):
|
|
1081
|
-
self.index.refresh()
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
class ElasticsearchAtomicIndexRebuilder(ElasticsearchIndexRebuilder):
|
|
1085
|
-
def __init__(self, index):
|
|
1086
|
-
self.alias = index
|
|
1087
|
-
self.index = index.backend.index_class(
|
|
1088
|
-
index.backend, self.alias.name + "_" + get_random_string(7).lower()
|
|
1089
|
-
)
|
|
1090
|
-
|
|
1091
|
-
def reset_index(self):
|
|
1092
|
-
# Delete old index using the alias
|
|
1093
|
-
# This should delete both the alias and the index
|
|
1094
|
-
self.alias.delete()
|
|
1095
|
-
|
|
1096
|
-
# Create new index
|
|
1097
|
-
self.index.put()
|
|
1098
|
-
|
|
1099
|
-
# Create a new alias
|
|
1100
|
-
self.index.put_alias(self.alias.name)
|
|
1101
|
-
|
|
1102
|
-
def start(self):
|
|
1103
|
-
# Create the new index
|
|
1104
|
-
self.index.put()
|
|
1105
|
-
|
|
1106
|
-
return self.index
|
|
1107
|
-
|
|
1108
|
-
def finish(self):
|
|
1109
|
-
self.index.refresh()
|
|
1110
|
-
|
|
1111
|
-
if self.alias.is_alias():
|
|
1112
|
-
# Update existing alias, then delete the old index
|
|
1113
|
-
|
|
1114
|
-
# Find index that alias currently points to, we'll delete it after
|
|
1115
|
-
# updating the alias
|
|
1116
|
-
old_index = self.alias.aliased_indices()
|
|
1117
|
-
|
|
1118
|
-
# Update alias to point to new index
|
|
1119
|
-
self.index.put_alias(self.alias.name)
|
|
1120
|
-
|
|
1121
|
-
# Delete old index
|
|
1122
|
-
# aliased_indices() can return multiple indices. Delete them all
|
|
1123
|
-
for index in old_index:
|
|
1124
|
-
if index.name != self.index.name:
|
|
1125
|
-
index.delete()
|
|
1126
|
-
|
|
1127
|
-
else:
|
|
1128
|
-
# self.alias doesn't currently refer to an alias in Elasticsearch.
|
|
1129
|
-
# This means that either nothing exists in ES with that name or
|
|
1130
|
-
# there is currently an index with the that name
|
|
1131
|
-
|
|
1132
|
-
# Run delete on the alias, just in case it is currently an index.
|
|
1133
|
-
# This happens on the first rebuild after switching ATOMIC_REBUILD on
|
|
1134
|
-
self.alias.delete()
|
|
1135
|
-
|
|
1136
|
-
# Create the alias
|
|
1137
|
-
self.index.put_alias(self.alias.name)
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
class Elasticsearch7SearchBackend(BaseSearchBackend):
|
|
1141
|
-
mapping_class = Elasticsearch7Mapping
|
|
1142
|
-
index_class = Elasticsearch7Index
|
|
30
|
+
class Elasticsearch7SearchBackend(IndexOptionMixin, _Elasticsearch7SearchBackend):
|
|
1143
31
|
query_compiler_class = Elasticsearch7SearchQueryCompiler
|
|
1144
32
|
autocomplete_query_compiler_class = Elasticsearch7AutocompleteQueryCompiler
|
|
1145
|
-
results_class = Elasticsearch7SearchResults
|
|
1146
|
-
basic_rebuilder_class = ElasticsearchIndexRebuilder
|
|
1147
|
-
atomic_rebuilder_class = ElasticsearchAtomicIndexRebuilder
|
|
1148
|
-
catch_indexing_errors = True
|
|
1149
|
-
timeout_kwarg_name = "timeout"
|
|
1150
|
-
|
|
1151
|
-
settings = {
|
|
1152
|
-
"settings": {
|
|
1153
|
-
"analysis": {
|
|
1154
|
-
"analyzer": {
|
|
1155
|
-
"ngram_analyzer": {
|
|
1156
|
-
"type": "custom",
|
|
1157
|
-
"tokenizer": "standard",
|
|
1158
|
-
"filter": ["asciifolding", "lowercase", "ngram"],
|
|
1159
|
-
},
|
|
1160
|
-
"edgengram_analyzer": {
|
|
1161
|
-
"type": "custom",
|
|
1162
|
-
"tokenizer": "standard",
|
|
1163
|
-
"filter": ["asciifolding", "lowercase", "edgengram"],
|
|
1164
|
-
},
|
|
1165
|
-
},
|
|
1166
|
-
"tokenizer": {
|
|
1167
|
-
"ngram_tokenizer": {
|
|
1168
|
-
"type": "ngram",
|
|
1169
|
-
"min_gram": 3,
|
|
1170
|
-
"max_gram": 15,
|
|
1171
|
-
},
|
|
1172
|
-
"edgengram_tokenizer": {
|
|
1173
|
-
"type": "edge_ngram",
|
|
1174
|
-
"min_gram": 2,
|
|
1175
|
-
"max_gram": 15,
|
|
1176
|
-
"side": "front",
|
|
1177
|
-
},
|
|
1178
|
-
},
|
|
1179
|
-
"filter": {
|
|
1180
|
-
"ngram": {"type": "ngram", "min_gram": 3, "max_gram": 15},
|
|
1181
|
-
"edgengram": {"type": "edge_ngram", "min_gram": 1, "max_gram": 15},
|
|
1182
|
-
},
|
|
1183
|
-
},
|
|
1184
|
-
"index": {
|
|
1185
|
-
"max_ngram_diff": 12,
|
|
1186
|
-
},
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
def _get_host_config_from_url(self, url):
|
|
1191
|
-
"""Given a parsed URL, return the host configuration to be added to self.hosts"""
|
|
1192
|
-
use_ssl = url.scheme == "https"
|
|
1193
|
-
port = url.port or (443 if use_ssl else 80)
|
|
1194
|
-
|
|
1195
|
-
http_auth = None
|
|
1196
|
-
if url.username is not None and url.password is not None:
|
|
1197
|
-
http_auth = (url.username, url.password)
|
|
1198
|
-
|
|
1199
|
-
return {
|
|
1200
|
-
"host": url.hostname,
|
|
1201
|
-
"port": port,
|
|
1202
|
-
"url_prefix": url.path,
|
|
1203
|
-
"use_ssl": use_ssl,
|
|
1204
|
-
"verify_certs": use_ssl,
|
|
1205
|
-
"http_auth": http_auth,
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
def _get_options_from_host_urls(self, urls):
|
|
1209
|
-
"""Given a list of parsed URLs, return a dict of additional options to be passed into the
|
|
1210
|
-
Elasticsearch constructor; necessary for options that aren't valid as part of the 'hosts' config
|
|
1211
|
-
"""
|
|
1212
|
-
return {}
|
|
1213
|
-
|
|
1214
|
-
def __init__(self, params):
|
|
1215
|
-
super().__init__(params)
|
|
1216
|
-
|
|
1217
|
-
# Get settings
|
|
1218
|
-
self.hosts = params.pop("HOSTS", None)
|
|
1219
|
-
self.index_name = params.pop("INDEX", "wagtail")
|
|
1220
|
-
self.timeout = params.pop("TIMEOUT", 10)
|
|
1221
|
-
|
|
1222
|
-
if params.pop("ATOMIC_REBUILD", False):
|
|
1223
|
-
self.rebuilder_class = self.atomic_rebuilder_class
|
|
1224
|
-
else:
|
|
1225
|
-
self.rebuilder_class = self.basic_rebuilder_class
|
|
1226
|
-
|
|
1227
|
-
self.settings = deepcopy(
|
|
1228
|
-
self.settings
|
|
1229
|
-
) # Make the class settings attribute as instance settings attribute
|
|
1230
|
-
self.settings = deep_update(self.settings, params.pop("INDEX_SETTINGS", {}))
|
|
1231
|
-
|
|
1232
|
-
# Get Elasticsearch interface
|
|
1233
|
-
# Any remaining params are passed into the Elasticsearch constructor
|
|
1234
|
-
options = params.pop("OPTIONS", {})
|
|
1235
|
-
|
|
1236
|
-
# If HOSTS is not set, convert URLS setting to HOSTS
|
|
1237
|
-
if self.hosts is None:
|
|
1238
|
-
es_urls = params.pop("URLS", ["http://localhost:9200"])
|
|
1239
|
-
# if es_urls is not a list, convert it to a list
|
|
1240
|
-
if isinstance(es_urls, str):
|
|
1241
|
-
es_urls = [es_urls]
|
|
1242
|
-
|
|
1243
|
-
parsed_urls = [urlparse(url) for url in es_urls]
|
|
1244
|
-
|
|
1245
|
-
self.hosts = [self._get_host_config_from_url(url) for url in parsed_urls]
|
|
1246
|
-
options.update(self._get_options_from_host_urls(parsed_urls))
|
|
1247
|
-
|
|
1248
|
-
options[self.timeout_kwarg_name] = self.timeout
|
|
1249
|
-
|
|
1250
|
-
self.es = Elasticsearch(hosts=self.hosts, **options)
|
|
1251
|
-
|
|
1252
|
-
def get_index_for_model(self, model):
|
|
1253
|
-
# Split models up into separate indices based on their root model.
|
|
1254
|
-
# For example, all page-derived models get put together in one index,
|
|
1255
|
-
# while images and documents each have their own index.
|
|
1256
|
-
root_model = get_model_root(model)
|
|
1257
|
-
index_suffix = (
|
|
1258
|
-
"__"
|
|
1259
|
-
+ root_model._meta.app_label.lower()
|
|
1260
|
-
+ "_"
|
|
1261
|
-
+ root_model.__name__.lower()
|
|
1262
|
-
)
|
|
1263
|
-
|
|
1264
|
-
return self.index_class(self, self.index_name + index_suffix)
|
|
1265
|
-
|
|
1266
|
-
def get_index(self):
|
|
1267
|
-
return self.index_class(self, self.index_name)
|
|
1268
|
-
|
|
1269
|
-
def get_rebuilder(self):
|
|
1270
|
-
return self.rebuilder_class(self.get_index())
|
|
1271
|
-
|
|
1272
|
-
def reset_index(self):
|
|
1273
|
-
# Use the rebuilder to reset the index
|
|
1274
|
-
self.get_rebuilder().reset_index()
|
|
1275
33
|
|
|
1276
34
|
|
|
1277
35
|
SearchBackend = Elasticsearch7SearchBackend
|