wagtail 7.1.2__py3-none-any.whl → 7.2rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wagtail/__init__.py +1 -1
- wagtail/actions/copy_page.py +1 -1
- wagtail/actions/create_alias.py +1 -1
- wagtail/actions/delete_page.py +1 -1
- wagtail/actions/publish_page_revision.py +1 -1
- wagtail/actions/publish_revision.py +1 -1
- wagtail/actions/revert_to_page_revision.py +1 -1
- wagtail/actions/unpublish.py +1 -1
- wagtail/actions/unpublish_page.py +1 -1
- wagtail/admin/auth.py +3 -1
- wagtail/admin/checks.py +2 -2
- wagtail/admin/filters.py +28 -1
- wagtail/admin/forms/collections.py +1 -1
- wagtail/admin/forms/comments.py +1 -1
- wagtail/admin/forms/models.py +1 -1
- wagtail/admin/forms/pages.py +1 -1
- wagtail/admin/forms/tags.py +1 -1
- wagtail/admin/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/cs/LC_MESSAGES/django.po +25 -1
- wagtail/admin/locale/en/LC_MESSAGES/django.po +278 -192
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +29 -15
- wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/django.po +3 -2
- wagtail/admin/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/nl/LC_MESSAGES/django.po +57 -3
- wagtail/admin/locale/nl/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/nl/LC_MESSAGES/djangojs.po +8 -2
- wagtail/admin/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ru/LC_MESSAGES/django.po +58 -1
- wagtail/admin/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/tr/LC_MESSAGES/django.po +3 -2
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
- wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +2 -2
- wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
- wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
- wagtail/admin/static/wagtailadmin/js/icons.js +1 -1
- wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +2 -2
- wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-transition.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery-3.6.0.min.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery-ui-1.13.2.min.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.datetimepicker.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload-process.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/jquery.iframe-transport.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor/tag-it.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +1 -1
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/templates/wagtailadmin/account/account.html +2 -0
- wagtail/admin/templates/wagtailadmin/base.html +14 -0
- wagtail/admin/templates/wagtailadmin/generic/chooser/chooser.html +2 -1
- wagtail/admin/templates/wagtailadmin/generic/chooser/creation_form.html +2 -1
- wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
- wagtail/admin/templates/wagtailadmin/panels/object_list.html +1 -1
- wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +3 -2
- wagtail/admin/templates/wagtailadmin/shared/formatted_field.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +19 -0
- wagtail/admin/templates/wagtailadmin/shared/panel.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/set_privacy.html +15 -0
- wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +28 -1
- wagtail/admin/templates/wagtailadmin/shared/workflow_history/detail.html +2 -2
- wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_header.html → tables/ordering_header.html} +2 -2
- wagtail/admin/templates/wagtailadmin/tables/title_cell.html +1 -1
- wagtail/admin/templates/wagtailadmin/widgets/{daterange_input.html → range_input.html} +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/task_chooser/chooser.html +4 -2
- wagtail/admin/templatetags/wagtailadmin_tags.py +41 -22
- wagtail/admin/tests/api/test_pages.py +7 -7
- wagtail/admin/tests/api/test_renderer_classes.py +16 -0
- wagtail/admin/tests/pages/test_create_page.py +34 -2
- wagtail/admin/tests/pages/test_edit_page.py +128 -14
- wagtail/admin/tests/pages/test_explorer_view.py +34 -7
- wagtail/admin/tests/pages/test_reorder_page.py +11 -0
- wagtail/admin/tests/test_collections_views.py +12 -0
- wagtail/admin/tests/test_edit_handlers.py +3 -3
- wagtail/admin/tests/test_filters.py +2 -2
- wagtail/admin/tests/test_keyboard_shortcuts.py +52 -2
- wagtail/admin/tests/test_menu.py +0 -2
- wagtail/admin/tests/test_privacy.py +16 -16
- wagtail/admin/tests/test_templatetags.py +137 -0
- wagtail/admin/tests/test_workflows.py +34 -0
- wagtail/admin/tests/viewsets/test_model_viewset.py +322 -0
- wagtail/admin/ui/tables/orderable.py +73 -0
- wagtail/admin/ui/tables/pages.py +3 -13
- wagtail/admin/views/collection_privacy.py +6 -2
- wagtail/admin/views/generic/__init__.py +1 -0
- wagtail/admin/views/generic/mixins.py +20 -2
- wagtail/admin/views/generic/models.py +67 -1
- wagtail/admin/views/generic/ordering.py +79 -0
- wagtail/admin/views/home.py +3 -3
- wagtail/admin/views/page_privacy.py +5 -2
- wagtail/admin/views/pages/create.py +1 -1
- wagtail/admin/views/pages/edit.py +2 -2
- wagtail/admin/views/pages/listing.py +7 -42
- wagtail/admin/views/pages/move.py +1 -1
- wagtail/admin/views/pages/ordering.py +1 -1
- wagtail/admin/viewsets/base.py +1 -1
- wagtail/admin/viewsets/model.py +49 -1
- wagtail/admin/wagtail_hooks.py +2 -1
- wagtail/admin/widgets/slug.py +10 -10
- wagtail/api/v2/serializers.py +1 -1
- wagtail/api/v2/tests/test_renderer_classes.py +32 -0
- wagtail/apps.py +2 -0
- wagtail/bin/wagtail.py +1 -1
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +14 -14
- wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.po +19 -2
- wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.po +18 -1
- wagtail/contrib/frontend_cache/tests.py +4 -2
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +4 -4
- wagtail/contrib/redirects/tests/test_tmp_storages.py +20 -0
- wagtail/contrib/redirects/tmp_storages.py +1 -1
- wagtail/contrib/redirects/views.py +3 -3
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.po +43 -3
- wagtail/contrib/search_promotions/static/wagtailsearchpromotions/js/query-chooser-modal.js +1 -1
- wagtail/contrib/search_promotions/views/settings.py +2 -2
- wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.po +6 -2
- wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.po +6 -1
- wagtail/contrib/settings/tests/site_specific/test_admin.py +40 -6
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/styleguide/templates/wagtailstyleguide/base.html +5 -5
- wagtail/contrib/table_block/blocks.py +1 -0
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +5 -1
- wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/coreutils.py +5 -5
- wagtail/documents/forms.py +18 -1
- wagtail/documents/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/documents/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/nl/LC_MESSAGES/django.po +9 -0
- wagtail/documents/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/ru/LC_MESSAGES/django.po +9 -0
- wagtail/documents/models.py +1 -1
- wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
- wagtail/documents/templates/wagtaildocs/documents/add.html +0 -34
- wagtail/documents/tests/test_admin_views.py +132 -26
- wagtail/documents/tests/test_collection_privacy.py +18 -4
- wagtail/documents/tests/test_form_overrides.py +1 -1
- wagtail/documents/tests/test_search.py +21 -8
- wagtail/documents/views/documents.py +1 -1
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/static/wagtailembeds/js/embed-chooser-modal.js +1 -1
- wagtail/images/forms.py +16 -1
- wagtail/images/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/cs/LC_MESSAGES/django.po +12 -1
- wagtail/images/locale/en/LC_MESSAGES/django.po +57 -46
- wagtail/images/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/nl/LC_MESSAGES/django.po +37 -14
- wagtail/images/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ru/LC_MESSAGES/django.po +20 -1
- wagtail/images/models.py +1 -1
- wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
- wagtail/images/static/wagtailimages/js/focal-point-chooser.js +1 -1
- wagtail/images/static/wagtailimages/js/image-block.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
- wagtail/images/static/wagtailimages/js/image-url-generator.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.Jcrop.min.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-image.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-validate.js +1 -1
- wagtail/images/static/wagtailimages/js/vendor/load-image.min.js +1 -1
- wagtail/images/templates/wagtailimages/chooser/chooser.html +22 -13
- wagtail/images/templates/wagtailimages/chooser/image_preview_column_cell.html +10 -0
- wagtail/images/templates/wagtailimages/chooser/results.html +24 -20
- wagtail/images/templates/wagtailimages/chooser/title_column_cell.html +15 -0
- wagtail/images/templates/wagtailimages/images/add.html +0 -34
- wagtail/images/templates/wagtailimages/images/index.html +3 -3
- wagtail/images/templates/wagtailimages/images/index_results.html +1 -1
- wagtail/images/templates/wagtailimages/images/layout_toggle_button.html +8 -7
- wagtail/images/templatetags/wagtailimages_tags.py +2 -2
- wagtail/images/tests/test_admin_views.py +87 -0
- wagtail/images/tests/test_form_overrides.py +1 -1
- wagtail/images/tests/test_models.py +48 -9
- wagtail/images/views/chooser.py +66 -2
- wagtail/locale/en/LC_MESSAGES/django.po +55 -55
- wagtail/locale/is_IS/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/is_IS/LC_MESSAGES/django.po +3 -3
- wagtail/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/nl/LC_MESSAGES/django.po +11 -2
- wagtail/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/ru/LC_MESSAGES/django.po +11 -1
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/nl/LC_MESSAGES/django.po +12 -1
- wagtail/locales/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/ru/LC_MESSAGES/django.po +10 -1
- wagtail/locales/views.py +2 -2
- wagtail/models/orderable.py +10 -0
- wagtail/models/pages.py +9 -11
- wagtail/models/sites.py +1 -1
- wagtail/models/workflows.py +8 -5
- wagtail/project_template/home/tests.py +6 -7
- wagtail/project_template/project_name/settings/base.py +9 -9
- wagtail/project_template/requirements.txt +1 -1
- wagtail/query.py +7 -2
- wagtail/rich_text/rewriters.py +1 -1
- wagtail/search/apps.py +4 -49
- wagtail/search/backends/__init__.py +1 -113
- wagtail/search/backends/base.py +1 -547
- wagtail/search/backends/database/__init__.py +1 -50
- wagtail/search/backends/database/fallback.py +1 -253
- wagtail/search/backends/database/mysql/mysql.py +1 -700
- wagtail/search/backends/database/mysql/query.py +1 -258
- wagtail/search/backends/database/postgres/postgres.py +1 -749
- wagtail/search/backends/database/postgres/query.py +1 -83
- wagtail/search/backends/database/postgres/weights.py +1 -63
- wagtail/search/backends/database/sqlite/query.py +1 -294
- wagtail/search/backends/database/sqlite/sqlite.py +1 -719
- wagtail/search/backends/database/sqlite/utils.py +1 -35
- wagtail/search/backends/deprecation.py +45 -0
- wagtail/search/backends/elasticsearch7.py +18 -1260
- wagtail/search/backends/elasticsearch8.py +21 -96
- wagtail/search/backends/elasticsearch9.py +35 -0
- wagtail/search/backends/opensearch2.py +35 -0
- wagtail/search/backends/opensearch3.py +35 -0
- wagtail/search/index.py +1 -358
- wagtail/search/locale/en/LC_MESSAGES/django.po +2 -10
- wagtail/search/management/commands/update_index.py +1 -205
- wagtail/search/management/commands/wagtail_update_index.py +1 -4
- wagtail/search/models.py +32 -158
- wagtail/search/query.py +1 -114
- wagtail/search/queryset.py +1 -43
- wagtail/search/signal_handlers.py +1 -24
- wagtail/search/tasks.py +1 -10
- wagtail/search/tests/test_elasticsearch.py +22 -0
- wagtail/search/utils.py +1 -206
- wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/snippets/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/ru/LC_MESSAGES/django.po +8 -1
- wagtail/snippets/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/tr/LC_MESSAGES/django.po +8 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
- wagtail/snippets/tests/test_reordering.py +319 -0
- wagtail/snippets/tests/test_snippets.py +65 -12
- wagtail/snippets/views/snippets.py +16 -0
- wagtail/test/numberformat.py +30 -0
- wagtail/test/settings.py +35 -12
- wagtail/test/testapp/fields.py +12 -0
- wagtail/test/testapp/migrations/0056_commentablejsonpage.py +50 -0
- wagtail/test/testapp/migrations/0057_featurecompletetoy_sort_order.py +23 -0
- wagtail/test/testapp/migrations/0058_customlocktask.py +31 -0
- wagtail/test/testapp/models.py +27 -0
- wagtail/test/testapp/views.py +3 -1
- wagtail/test/utils/page_tests.py +17 -17
- wagtail/test/utils/template_tests.py +4 -6
- wagtail/test/utils/wagtail_tests.py +1 -2
- wagtail/tests/test_page_model.py +15 -0
- wagtail/{search/tests → tests}/test_page_search.py +29 -2
- wagtail/tests/test_search_fields.py +69 -0
- wagtail/tests/test_tests.py +62 -6
- wagtail/tests/test_workflow.py +25 -1
- wagtail/users/locale/cs/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/cs/LC_MESSAGES/django.po +3 -0
- wagtail/users/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/nl/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/nl/LC_MESSAGES/django.po +6 -3
- wagtail/users/locale/ru/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/ru/LC_MESSAGES/django.po +5 -1
- wagtail/users/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/tr/LC_MESSAGES/django.po +78 -4
- wagtail/users/templates/wagtailusers/users/create.html +2 -0
- wagtail/users/templates/wagtailusers/users/edit.html +2 -0
- wagtail/users/tests/test_admin_views.py +4 -0
- wagtail/users/views/users.py +1 -1
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/METADATA +7 -6
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/RECORD +309 -315
- wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +0 -13
- wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +0 -13
- wagtail/search/tests/__init__.py +0 -0
- wagtail/search/tests/elasticsearch_common_tests.py +0 -251
- wagtail/search/tests/test_backends.py +0 -1215
- wagtail/search/tests/test_db_backend.py +0 -62
- wagtail/search/tests/test_elasticsearch7_backend.py +0 -1452
- wagtail/search/tests/test_elasticsearch8_backend.py +0 -15
- wagtail/search/tests/test_index_functions.py +0 -256
- wagtail/search/tests/test_indexed_class.py +0 -157
- wagtail/search/tests/test_mysql_backend.py +0 -192
- wagtail/search/tests/test_postgres_backend.py +0 -210
- wagtail/search/tests/test_queries.py +0 -332
- wagtail/search/tests/test_related_fields.py +0 -102
- wagtail/search/tests/test_sqlite_backend.py +0 -52
- wagtail/test/search/__init__.py +0 -0
- wagtail/test/search/apps.py +0 -9
- wagtail/test/search/fixtures/search.json +0 -545
- wagtail/test/search/migrations/0001_initial.py +0 -146
- wagtail/test/search/migrations/0002_bookunindexed.py +0 -43
- wagtail/test/search/migrations/0003_book_summary.py +0 -18
- wagtail/test/search/migrations/__init__.py +0 -0
- wagtail/test/search/models.py +0 -137
- /wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_cell.html → tables/ordering_cell.html} +0 -0
- /wagtail/{search/checks.py → checks.py} +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/WHEEL +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/licenses/LICENSE +0 -0
- {wagtail-7.1.2.dist-info → wagtail-7.2rc1.dist-info}/top_level.txt +0 -0
|
@@ -1,258 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
from typing import Any, Union
|
|
3
|
-
|
|
4
|
-
from django.db.backends.base.base import BaseDatabaseWrapper
|
|
5
|
-
from django.db.models.expressions import CombinedExpression, Expression, Value
|
|
6
|
-
from django.db.models.fields import BooleanField, Field
|
|
7
|
-
from django.db.models.sql.compiler import SQLCompiler
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class LexemeCombinable(Expression):
|
|
11
|
-
BITAND = "+"
|
|
12
|
-
BITOR = ""
|
|
13
|
-
invert = False # By default, it is not inverted
|
|
14
|
-
|
|
15
|
-
def _combine(self, other, connector, reversed, node=None):
|
|
16
|
-
if not isinstance(other, LexemeCombinable):
|
|
17
|
-
raise TypeError(
|
|
18
|
-
f"Lexeme can only be combined with other Lexemes, got {type(other)}."
|
|
19
|
-
)
|
|
20
|
-
if reversed:
|
|
21
|
-
return CombinedLexeme(other, connector, self)
|
|
22
|
-
return CombinedLexeme(self, connector, other)
|
|
23
|
-
|
|
24
|
-
# On Combinable, these are not implemented to reduce confusion with Q. In
|
|
25
|
-
# this case we are actually (ab)using them to do logical combination so
|
|
26
|
-
# it's consistent with other usage in Django.
|
|
27
|
-
def bitand(self, other):
|
|
28
|
-
return self._combine(other, self.BITAND, False)
|
|
29
|
-
|
|
30
|
-
def bitor(self, other):
|
|
31
|
-
return self._combine(other, self.BITOR, False)
|
|
32
|
-
|
|
33
|
-
def __or__(self, other):
|
|
34
|
-
return self._combine(other, self.BITOR, False)
|
|
35
|
-
|
|
36
|
-
def __and__(self, other):
|
|
37
|
-
return self._combine(other, self.BITAND, False)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class SearchQueryField(Field):
|
|
41
|
-
def db_type(self, connection):
|
|
42
|
-
return None
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class Lexeme(LexemeCombinable, Value):
|
|
46
|
-
_output_field = SearchQueryField()
|
|
47
|
-
|
|
48
|
-
def __init__(
|
|
49
|
-
self, value, output_field=None, invert=False, prefix=False, weight=None
|
|
50
|
-
):
|
|
51
|
-
self.prefix = prefix
|
|
52
|
-
self.invert = invert
|
|
53
|
-
self.weight = weight
|
|
54
|
-
|
|
55
|
-
if not value:
|
|
56
|
-
raise ValueError("Lexeme value cannot be empty.")
|
|
57
|
-
if re.search(r"\W+", value):
|
|
58
|
-
raise ValueError(
|
|
59
|
-
f"Lexeme value '{value}' must consist of alphanumeric characters and '_' only."
|
|
60
|
-
)
|
|
61
|
-
super().__init__(value, output_field=output_field)
|
|
62
|
-
|
|
63
|
-
def as_sql(self, compiler, connection):
|
|
64
|
-
param = self.value
|
|
65
|
-
template = "%s"
|
|
66
|
-
|
|
67
|
-
if self.prefix:
|
|
68
|
-
param = f"{param}*"
|
|
69
|
-
if self.invert:
|
|
70
|
-
param = f"(-{param})"
|
|
71
|
-
else:
|
|
72
|
-
param = f"{param}"
|
|
73
|
-
|
|
74
|
-
return template, [param]
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
class CombinedLexeme(LexemeCombinable):
|
|
78
|
-
_output_field = SearchQueryField()
|
|
79
|
-
|
|
80
|
-
def __init__(self, lhs, connector, rhs, output_field=None):
|
|
81
|
-
super().__init__(output_field=output_field)
|
|
82
|
-
self.connector = connector
|
|
83
|
-
self.lhs = lhs
|
|
84
|
-
self.rhs = rhs
|
|
85
|
-
|
|
86
|
-
def as_sql(self, compiler, connection):
|
|
87
|
-
value_params = []
|
|
88
|
-
|
|
89
|
-
lhs_connector = self.connector
|
|
90
|
-
rhs_connector = self.connector
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
self.lhs.invert and self.connector == "+"
|
|
94
|
-
): # NOTE: This is a special case for MySQL. If either side's operator is AND (+), and it is inverted, the operator should become NOT (-). If we did nothing, the result could would be '+X +(-Y)' for And(X, Not(Y)), which seems correct, but produces a wrong result. The solution is to turn the query into '+X -Y', which does work, and therefore this is done here.
|
|
95
|
-
# TODO: There may be a better solution than this.
|
|
96
|
-
modified_value = self.lhs.value.copy()
|
|
97
|
-
modified_value.invert = not modified_value.invert
|
|
98
|
-
lhs_connector = "-"
|
|
99
|
-
lsql, params = compiler.compile(modified_value)
|
|
100
|
-
else:
|
|
101
|
-
lsql, params = compiler.compile(self.lhs)
|
|
102
|
-
value_params.extend(params)
|
|
103
|
-
|
|
104
|
-
if self.rhs.invert and self.connector == "+": # Same explanation as above.
|
|
105
|
-
modified_value = self.rhs.value.copy()
|
|
106
|
-
modified_value.invert = not modified_value.invert
|
|
107
|
-
rhs_connector = "-"
|
|
108
|
-
rsql, params = compiler.compile(modified_value)
|
|
109
|
-
else:
|
|
110
|
-
rsql, params = compiler.compile(self.rhs)
|
|
111
|
-
value_params.extend(params)
|
|
112
|
-
|
|
113
|
-
combined_sql = "({}{} {}{})".format(
|
|
114
|
-
lhs_connector, lsql, rhs_connector, rsql
|
|
115
|
-
) # if self.connector is '+' (AND), then both terms will be ANDed together. We need to repeat the connector to make that work.
|
|
116
|
-
combined_value = combined_sql % tuple(value_params)
|
|
117
|
-
return "%s", [combined_value]
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
class SearchQueryCombinable:
|
|
121
|
-
BITAND = "+"
|
|
122
|
-
BITOR = ""
|
|
123
|
-
|
|
124
|
-
def _combine(self, other, connector: str, reversed: bool = False):
|
|
125
|
-
if not isinstance(other, SearchQueryCombinable):
|
|
126
|
-
raise TypeError(
|
|
127
|
-
"SearchQuery can only be combined with other SearchQuery "
|
|
128
|
-
"instances, got %s." % type(other).__name__
|
|
129
|
-
)
|
|
130
|
-
if reversed:
|
|
131
|
-
return CombinedSearchQuery(other, connector, self)
|
|
132
|
-
return CombinedSearchQuery(self, connector, other)
|
|
133
|
-
|
|
134
|
-
# On Combinable, these are not implemented to reduce confusion with Q. In
|
|
135
|
-
# this case we are actually (ab)using them to do logical combination so
|
|
136
|
-
# it's consistent with other usage in Django.
|
|
137
|
-
def __or__(self, other):
|
|
138
|
-
return self._combine(other, self.BITOR, False)
|
|
139
|
-
|
|
140
|
-
def __ror__(self, other):
|
|
141
|
-
return self._combine(other, self.BITOR, True)
|
|
142
|
-
|
|
143
|
-
def __and__(self, other):
|
|
144
|
-
return self._combine(other, self.BITAND, False)
|
|
145
|
-
|
|
146
|
-
def __rand__(self, other):
|
|
147
|
-
return self._combine(other, self.BITAND, True)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
class SearchQuery(SearchQueryCombinable, Expression):
|
|
151
|
-
def __init__(
|
|
152
|
-
self, value: Union[LexemeCombinable, str], search_type: str = "lexeme", **extra
|
|
153
|
-
):
|
|
154
|
-
super().__init__(output_field=SearchQueryField())
|
|
155
|
-
self.extra = extra
|
|
156
|
-
if (
|
|
157
|
-
isinstance(value, str) or search_type == "phrase"
|
|
158
|
-
): # If the value is a string, we assume it's a phrase
|
|
159
|
-
safe_string = re.sub(
|
|
160
|
-
r"\W+", " ", value
|
|
161
|
-
) # Remove non-word characters. This is done to disallow the usage of full text search operators in the MATCH clause, because MySQL doesn't include these kinds of characters in FULLTEXT indexes.
|
|
162
|
-
self.value = Value(
|
|
163
|
-
'"%s"' % safe_string
|
|
164
|
-
) # We wrap it in quotes to make sure it's parsed as a phrase
|
|
165
|
-
else: # Otherwise, we assume it's a lexeme
|
|
166
|
-
self.value = value
|
|
167
|
-
|
|
168
|
-
def as_sql(
|
|
169
|
-
self,
|
|
170
|
-
compiler: SQLCompiler,
|
|
171
|
-
connection: BaseDatabaseWrapper,
|
|
172
|
-
**extra_context: Any,
|
|
173
|
-
) -> tuple[str, list[Any]]:
|
|
174
|
-
sql, params = compiler.compile(self.value)
|
|
175
|
-
return (sql, params)
|
|
176
|
-
|
|
177
|
-
def __repr__(self) -> str:
|
|
178
|
-
return self.value.__repr__()
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
class CombinedSearchQuery(SearchQueryCombinable, CombinedExpression):
|
|
182
|
-
def __init__(self, lhs, connector, rhs, output_field=None):
|
|
183
|
-
super().__init__(lhs, connector, rhs, output_field)
|
|
184
|
-
|
|
185
|
-
def __str__(self):
|
|
186
|
-
return "%s" % super().__str__()
|
|
187
|
-
|
|
188
|
-
def as_sql(self, compiler, connection):
|
|
189
|
-
value_params = []
|
|
190
|
-
|
|
191
|
-
lhs_connector = self.connector
|
|
192
|
-
rhs_connector = self.connector
|
|
193
|
-
|
|
194
|
-
if (
|
|
195
|
-
isinstance(self.lhs, SearchQuery)
|
|
196
|
-
and isinstance(self.lhs.value, Lexeme)
|
|
197
|
-
and self.lhs.value.invert
|
|
198
|
-
and self.connector == "+"
|
|
199
|
-
): # NOTE: The explanation for this special case is the same as above, in the CombinedLexeme class.
|
|
200
|
-
modified_value = self.lhs.value.copy()
|
|
201
|
-
modified_value.invert = not modified_value.invert
|
|
202
|
-
lhs_connector = "-"
|
|
203
|
-
lsql, params = compiler.compile(modified_value)
|
|
204
|
-
else:
|
|
205
|
-
lsql, params = compiler.compile(self.lhs)
|
|
206
|
-
value_params.extend(params)
|
|
207
|
-
|
|
208
|
-
if (
|
|
209
|
-
isinstance(self.rhs, SearchQuery)
|
|
210
|
-
and isinstance(self.rhs.value, Lexeme)
|
|
211
|
-
and self.rhs.value.invert
|
|
212
|
-
and self.connector == "+"
|
|
213
|
-
): # NOTE: The explanation for this special case is the same as above, in the CombinedLexeme class.
|
|
214
|
-
modified_value = self.rhs.value.copy()
|
|
215
|
-
modified_value.invert = not modified_value.invert
|
|
216
|
-
rhs_connector = "-"
|
|
217
|
-
rsql, params = compiler.compile(modified_value)
|
|
218
|
-
else:
|
|
219
|
-
rsql, params = compiler.compile(self.rhs)
|
|
220
|
-
value_params.extend(params)
|
|
221
|
-
|
|
222
|
-
combined_sql = "({}{} {}{})".format(
|
|
223
|
-
lhs_connector, lsql, rhs_connector, rsql
|
|
224
|
-
) # if self.connector is '+' (AND), then both terms will be ANDed together. We need to repeat the connector to make that work.
|
|
225
|
-
combined_value = combined_sql % tuple(value_params)
|
|
226
|
-
return "%s", [combined_value]
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
class MatchExpression(Expression):
|
|
230
|
-
filterable = True
|
|
231
|
-
template = "MATCH (%s) AGAINST (%s IN BOOLEAN MODE)"
|
|
232
|
-
|
|
233
|
-
def __init__(
|
|
234
|
-
self,
|
|
235
|
-
query: SearchQueryCombinable,
|
|
236
|
-
columns: list[str] = None,
|
|
237
|
-
output_field: Field = BooleanField(),
|
|
238
|
-
) -> None:
|
|
239
|
-
super().__init__(output_field=output_field)
|
|
240
|
-
self.query = query
|
|
241
|
-
self.columns = (
|
|
242
|
-
columns
|
|
243
|
-
or [
|
|
244
|
-
"title",
|
|
245
|
-
"body",
|
|
246
|
-
]
|
|
247
|
-
) # We need to provide a default list of columns if the user doesn't specify one. We have a joint index for for 'title' and 'body' (see wagtail.search.migrations.0006_customise_indexentry), so we'll pick that one.
|
|
248
|
-
|
|
249
|
-
def as_sql(self, compiler, connection):
|
|
250
|
-
compiled_query = compiler.compile(self.query) # Compile the query to a string
|
|
251
|
-
formatted_query = compiled_query[0] % tuple(
|
|
252
|
-
compiled_query[1]
|
|
253
|
-
) # Substitute the params in the query
|
|
254
|
-
column_list = ", ".join(
|
|
255
|
-
[f"`{column}`" for column in self.columns]
|
|
256
|
-
) # ['title', 'body'] becomes '`title`, `body`'
|
|
257
|
-
params = [formatted_query]
|
|
258
|
-
return (self.template % (column_list, "%s"), params)
|
|
1
|
+
from wagtailmodelsearch.backends.database.mysql.query import * # noqa: F403
|