wagtail 6.0.1__py3-none-any.whl → 6.1rc1__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/admin/checks.py +51 -0
- wagtail/admin/compare.py +1 -1
- wagtail/admin/filters.py +70 -1
- wagtail/admin/forms/account.py +1 -1
- wagtail/admin/forms/collections.py +15 -0
- wagtail/admin/forms/pages.py +49 -0
- wagtail/admin/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ca/LC_MESSAGES/django.po +122 -0
- wagtail/admin/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/de/LC_MESSAGES/django.po +5 -5
- wagtail/admin/locale/en/LC_MESSAGES/django.po +474 -385
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +3 -3
- wagtail/admin/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/es/LC_MESSAGES/django.po +6 -6
- wagtail/admin/locale/fr/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/fr/LC_MESSAGES/django.po +70 -3
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/django.po +2 -6
- wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/he_IL/LC_MESSAGES/djangojs.po +2 -2
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hr_HR/LC_MESSAGES/django.po +4 -0
- wagtail/admin/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/hu/LC_MESSAGES/django.po +142 -2
- wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/django.po +80 -8
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.mo +0 -0
- wagtail/admin/locale/it/LC_MESSAGES/djangojs.po +14 -2
- wagtail/admin/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/lv/LC_MESSAGES/django.po +154 -1
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +73 -2
- wagtail/admin/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/ro/LC_MESSAGES/django.po +3 -3
- wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/django.po +145 -2
- wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sv/LC_MESSAGES/django.po +77 -3
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.po +17 -1
- wagtail/admin/panels/comment_panel.py +1 -1
- wagtail/admin/panels/field_panel.py +1 -1
- wagtail/admin/rich_text/converters/editor_html.py +3 -1
- wagtail/admin/rich_text/editors/draftail/__init__.py +28 -2
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
- wagtail/admin/static/wagtailadmin/images/favicon.ico +0 -0
- 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 +1 -1
- 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/expanding-formset.js +1 -1
- wagtail/admin/static/wagtailadmin/js/filtered-select.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/preview-panel.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/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +4 -4
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/staticfiles.py +1 -0
- wagtail/admin/templates/wagtailadmin/admin_base.html +1 -0
- wagtail/admin/templates/wagtailadmin/base.html +1 -0
- wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +3 -1
- wagtail/admin/templates/wagtailadmin/collections/edit.html +0 -1
- wagtail/admin/templates/wagtailadmin/collections/index_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/generic/base.html +1 -9
- wagtail/admin/templates/wagtailadmin/generic/form.html +4 -2
- wagtail/admin/templates/wagtailadmin/generic/history/action_cell.html +27 -0
- wagtail/admin/templates/wagtailadmin/generic/index_results.html +8 -0
- wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +3 -4
- wagtail/admin/templates/wagtailadmin/icons/keyboard.svg +1 -0
- wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +3 -1
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -15
- wagtail/admin/templates/wagtailadmin/pages/action_menu/save_draft.html +3 -1
- wagtail/admin/templates/wagtailadmin/pages/choose_parent.html +17 -0
- wagtail/admin/templates/wagtailadmin/pages/explorable_index.html +8 -0
- wagtail/admin/templates/wagtailadmin/pages/history.html +1 -61
- wagtail/admin/templates/wagtailadmin/pages/index.html +1 -5
- wagtail/admin/templates/wagtailadmin/pages/listing/_locked_indicator.html +2 -2
- wagtail/admin/templates/wagtailadmin/pages/listing/_page_title_column_header.html +25 -27
- wagtail/admin/templates/wagtailadmin/pages/page_listing_header.html +2 -1
- wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
- wagtail/admin/templates/wagtailadmin/panels/publishing/schedule_publishing_panel.html +3 -1
- wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/active_filters.html +2 -1
- wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +8 -0
- wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/headers/page_edit_header.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +21 -9
- wagtail/admin/templates/wagtailadmin/shared/human_readable_date.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +29 -0
- wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +2 -1
- wagtail/admin/templates/wagtailadmin/skeleton.html +2 -1
- wagtail/admin/templates/wagtailadmin/tables/related_objects_cell.html +9 -0
- wagtail/admin/templates/wagtailadmin/tables/title_cell.html +9 -7
- wagtail/admin/templates/wagtailadmin/widgets/draftail_rich_text_area.html +1 -1
- wagtail/admin/templates/wagtailadmin/workflows/create.html +6 -23
- wagtail/admin/templates/wagtailadmin/workflows/create_task.html +6 -15
- wagtail/admin/templates/wagtailadmin/workflows/edit.html +6 -23
- wagtail/admin/templates/wagtailadmin/workflows/edit_task.html +6 -13
- wagtail/admin/templates/wagtailadmin/workflows/includes/task_usage_cell.html +4 -4
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_tasks_cell.html +18 -0
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_title_cell.html +7 -0
- wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_used_by_cell.html +25 -0
- wagtail/admin/templates/wagtailadmin/workflows/index.html +0 -99
- wagtail/admin/templates/wagtailadmin/workflows/index_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/workflows/task_index.html +0 -30
- wagtail/admin/templates/wagtailadmin/workflows/task_index_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/workflows/usage.html +1 -1
- wagtail/admin/templatetags/wagtailadmin_tags.py +116 -39
- wagtail/admin/tests/api/test_pages.py +26 -10
- wagtail/admin/tests/pages/test_create_page.py +10 -4
- wagtail/admin/tests/pages/test_custom_listing.py +37 -0
- wagtail/admin/tests/pages/test_edit_page.py +6 -6
- wagtail/admin/tests/pages/test_explorer_view.py +19 -18
- wagtail/admin/tests/pages/test_move_page.py +1 -1
- wagtail/admin/tests/pages/test_page_usage.py +50 -2
- wagtail/admin/tests/pages/test_parent_page_chooser_view.py +119 -0
- wagtail/admin/tests/pages/test_preview.py +18 -4
- wagtail/admin/tests/test_account_management.py +20 -1
- wagtail/admin/tests/test_audit_log.py +172 -5
- wagtail/admin/tests/test_checks.py +92 -0
- wagtail/admin/tests/test_collections_views.py +19 -5
- wagtail/admin/tests/test_compare.py +6 -6
- wagtail/admin/tests/test_dashboard.py +404 -0
- wagtail/admin/tests/test_dbwhitelister.py +4 -5
- wagtail/admin/tests/test_edit_handlers.py +2 -2
- wagtail/admin/tests/test_keyboard_shortcuts.py +84 -0
- wagtail/admin/tests/test_page_chooser.py +31 -18
- wagtail/admin/tests/test_privacy.py +36 -2
- wagtail/admin/tests/test_rich_text.py +168 -23
- wagtail/admin/tests/test_templatetags.py +411 -43
- wagtail/admin/tests/test_views.py +4 -2
- wagtail/admin/tests/test_workflows.py +531 -9
- wagtail/admin/tests/tests.py +3 -1
- wagtail/admin/tests/ui/test_tables.py +48 -1
- wagtail/admin/tests/viewsets/test_model_viewset.py +130 -23
- wagtail/admin/ui/side_panels.py +3 -1
- wagtail/admin/ui/tables/__init__.py +13 -1
- wagtail/admin/ui/tables/pages.py +17 -6
- wagtail/admin/urls/__init__.py +8 -3
- wagtail/admin/urls/pages.py +5 -0
- wagtail/admin/urls/workflows.py +10 -0
- wagtail/admin/views/chooser.py +20 -24
- wagtail/admin/views/collections.py +17 -1
- wagtail/admin/views/generic/base.py +34 -4
- wagtail/admin/views/generic/history.py +220 -51
- wagtail/admin/views/generic/mixins.py +7 -4
- wagtail/admin/views/generic/models.py +54 -47
- wagtail/admin/views/generic/multiple_upload.py +17 -8
- wagtail/admin/views/generic/usage.py +17 -11
- wagtail/admin/views/home.py +15 -12
- wagtail/admin/views/mixins.py +30 -0
- wagtail/admin/views/pages/choose_parent.py +73 -0
- wagtail/admin/views/pages/history.py +54 -66
- wagtail/admin/views/pages/listing.py +187 -106
- wagtail/admin/views/pages/usage.py +6 -1
- wagtail/admin/views/pages/utils.py +70 -1
- wagtail/admin/views/workflows.py +150 -21
- wagtail/admin/viewsets/model.py +2 -2
- wagtail/admin/viewsets/pages.py +77 -0
- wagtail/admin/wagtail_hooks.py +40 -2
- wagtail/admin/widgets/button.py +10 -10
- wagtail/api/v2/filters.py +1 -1
- wagtail/api/v2/tests/test_pages.py +1 -1
- wagtail/blocks/base.py +18 -9
- wagtail/blocks/field_block.py +9 -7
- wagtail/blocks/list_block.py +16 -6
- wagtail/blocks/static_block.py +3 -0
- wagtail/blocks/stream_block.py +58 -23
- wagtail/blocks/struct_block.py +15 -9
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +39 -47
- wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/forms/models.py +5 -5
- wagtail/contrib/forms/templates/wagtailforms/list_submissions.html +44 -33
- wagtail/contrib/forms/templates/wagtailforms/submissions_index.html +2 -63
- wagtail/contrib/forms/tests/test_models.py +26 -0
- wagtail/contrib/forms/urls.py +6 -0
- wagtail/contrib/forms/views.py +52 -49
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +34 -42
- wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/redirects/signal_handlers.py +1 -1
- wagtail/contrib/redirects/templates/wagtailredirects/index.html +1 -36
- wagtail/contrib/redirects/templates/wagtailredirects/index_results.html +18 -0
- wagtail/contrib/redirects/templates/wagtailredirects/redirect_target_cell.html +8 -0
- wagtail/contrib/redirects/tests/test_import_command.py +1 -1
- wagtail/contrib/redirects/tests/test_redirects.py +79 -8
- wagtail/contrib/redirects/urls.py +2 -1
- wagtail/contrib/redirects/views.py +85 -55
- wagtail/contrib/search_promotions/admin_urls.py +2 -1
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +41 -64
- wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.po +41 -2
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +9 -3
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +1 -16
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index_results.html +11 -0
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/list.html +0 -51
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/results.html +3 -16
- wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/search_promotion_column.html +15 -0
- wagtail/contrib/search_promotions/tests.py +122 -9
- wagtail/contrib/search_promotions/views.py +66 -65
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/contrib/settings/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/settings/locale/tr/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/settings/locale/tr/LC_MESSAGES/django.po +6 -2
- wagtail/contrib/settings/registry.py +10 -5
- wagtail/contrib/settings/tests/generic/test_admin.py +9 -0
- wagtail/contrib/settings/tests/site_specific/test_admin.py +10 -1
- wagtail/contrib/settings/tests/site_specific/test_model.py +3 -3
- wagtail/contrib/settings/tests/site_specific/test_templates.py +1 -1
- wagtail/contrib/settings/views.py +3 -1
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/simple_translation/tests/test_wagtail_hooks.py +2 -2
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
- wagtail/contrib/styleguide/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/styleguide/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/contrib/table_block/blocks.py +2 -2
- wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.po +27 -2
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.po +27 -2
- wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.po +27 -2
- wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
- wagtail/contrib/table_block/tests.py +6 -0
- wagtail/contrib/typed_table_block/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/ca/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/typed_table_block/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/hu/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/typed_table_block/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/contrib/typed_table_block/locale/it/LC_MESSAGES/django.po +12 -2
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/coreutils.py +3 -2
- wagtail/documents/admin_urls.py +2 -2
- wagtail/documents/locale/en/LC_MESSAGES/django.po +22 -22
- wagtail/documents/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/documents/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/hr_HR/LC_MESSAGES/django.po +19 -2
- wagtail/documents/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/hu/LC_MESSAGES/django.po +16 -2
- wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/it/LC_MESSAGES/django.po +19 -2
- wagtail/documents/migrations/0013_delete_uploadeddocument.py +16 -0
- wagtail/documents/models.py +1 -20
- wagtail/documents/rich_text/__init__.py +11 -7
- 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/index.html +0 -16
- wagtail/documents/tests/test_admin_views.py +155 -23
- wagtail/documents/tests/test_collection_privacy.py +55 -1
- wagtail/documents/tests/test_rich_text.py +14 -0
- wagtail/documents/views/documents.py +25 -22
- wagtail/documents/views/multiple.py +6 -7
- wagtail/documents/views/serve.py +16 -1
- wagtail/documents/wagtail_hooks.py +20 -15
- wagtail/embeds/blocks.py +5 -0
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/embeds/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/embeds/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/embeds/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/embeds/rich_text/__init__.py +1 -1
- wagtail/embeds/tests/test_rich_text.py +14 -0
- wagtail/embeds/wagtail_hooks.py +4 -14
- wagtail/fields.py +3 -48
- wagtail/images/admin_urls.py +2 -2
- wagtail/images/check_files/wagtail.jpg +0 -0
- wagtail/images/check_files/wagtail.png +0 -0
- wagtail/images/fields.py +2 -0
- wagtail/images/image_operations.py +1 -1
- wagtail/images/locale/ca/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/ca/LC_MESSAGES/django.po +12 -0
- wagtail/images/locale/en/LC_MESSAGES/django.po +33 -45
- wagtail/images/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/images/locale/hu/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/hu/LC_MESSAGES/django.po +28 -2
- wagtail/images/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/it/LC_MESSAGES/django.po +14 -2
- wagtail/images/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +4 -0
- wagtail/images/migrations/0026_delete_uploadedimage.py +16 -0
- wagtail/images/models.py +49 -43
- wagtail/images/rich_text/__init__.py +18 -8
- 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/templates/wagtailimages/images/image_listing_header.html +6 -0
- wagtail/images/templates/wagtailimages/images/index.html +11 -51
- wagtail/images/tests/test_admin_views.py +119 -62
- wagtail/images/tests/test_image_operations.py +10 -0
- wagtail/images/tests/test_models.py +35 -33
- wagtail/images/tests/test_rich_text.py +14 -0
- wagtail/images/tests/utils.py +1 -1
- wagtail/images/views/images.py +35 -64
- wagtail/images/views/multiple.py +6 -7
- wagtail/images/wagtail_hooks.py +4 -14
- wagtail/locale/en/LC_MESSAGES/django.po +150 -136
- wagtail/locale/es/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/es/LC_MESSAGES/django.po +3 -2
- wagtail/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/locale/it/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/it/LC_MESSAGES/django.po +5 -5
- wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/locale/sl/LC_MESSAGES/django.po +27 -2
- wagtail/locales/locale/ar/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/be/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/bg/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ca/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/cs/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/cy/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/da/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/de/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/el/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/es/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/et/LC_MESSAGES/django.po +2 -2
- wagtail/locales/locale/fa/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/fi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/fr/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/gl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/locales/locale/he_IL/LC_MESSAGES/django.po +3 -3
- wagtail/locales/locale/hr_HR/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/hu/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/id_ID/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/is_IS/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/it/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ja/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ko/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/lt/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/lv/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/mi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/mn/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/my/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nb/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/nl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pt_BR/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/pt_PT/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ro/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/ru/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sk_SK/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sl/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/sv/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tet/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/th/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tr/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/tr_TR/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/uk/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/vi/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
- wagtail/locales/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
- wagtail/locales/tests.py +18 -3
- wagtail/locales/views.py +0 -1
- wagtail/management/commands/rebuild_references_index.py +3 -1
- wagtail/migrations/0092_alter_collectionviewrestriction_password_and_more.py +33 -0
- wagtail/migrations/0093_uploadedfile.py +53 -0
- wagtail/models/__init__.py +147 -32
- wagtail/models/i18n.py +1 -1
- wagtail/models/{collections.py → media.py} +33 -2
- wagtail/models/reference_index.py +1 -1
- wagtail/models/view_restrictions.py +10 -3
- wagtail/project_template/project_name/settings/base.py +6 -0
- wagtail/project_template/requirements.txt +1 -1
- wagtail/rich_text/__init__.py +25 -8
- wagtail/rich_text/pages.py +19 -8
- wagtail/rich_text/rewriters.py +140 -68
- wagtail/search/backends/database/mysql/mysql.py +3 -3
- wagtail/search/backends/database/postgres/postgres.py +3 -3
- wagtail/search/backends/database/sqlite/sqlite.py +2 -2
- wagtail/search/backends/elasticsearch7.py +4 -0
- wagtail/search/locale/en/LC_MESSAGES/django.po +3 -3
- wagtail/search/tests/test_postgres_backend.py +50 -0
- wagtail/sites/locale/en/LC_MESSAGES/django.po +8 -8
- wagtail/sites/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/sites/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/sites/locale/ro/LC_MESSAGES/django.mo +0 -0
- wagtail/sites/locale/ro/LC_MESSAGES/django.po +3 -2
- wagtail/sites/tests.py +35 -9
- wagtail/sites/views.py +3 -1
- wagtail/snippets/locale/de/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/de/LC_MESSAGES/django.po +7 -8
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +16 -56
- wagtail/snippets/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/snippets/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.po +6 -2
- wagtail/snippets/locale/lv/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/lv/LC_MESSAGES/django.po +12 -0
- wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
- wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.po +4 -0
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/publish.html +3 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/save.html +3 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/create.html +2 -3
- wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +2 -3
- wagtail/snippets/tests/test_preview.py +13 -2
- wagtail/snippets/tests/test_snippets.py +41 -16
- wagtail/snippets/tests/test_viewset.py +95 -18
- wagtail/snippets/tests/test_workflows.py +12 -0
- wagtail/snippets/views/snippets.py +1 -40
- wagtail/templatetags/wagtailcore_tags.py +1 -1
- wagtail/test/demosite/models.py +1 -1
- wagtail/test/middleware.py +14 -1
- wagtail/test/testapp/fixtures/test.json +20 -0
- wagtail/test/testapp/migrations/0001_squashed_0073_revisablechildmodel_secret_text.py +8 -8
- wagtail/test/testapp/migrations/0023_snippetchoosermodel_full_featured.py +1 -0
- wagtail/test/testapp/migrations/0034_custompermissionmodel.py +44 -0
- wagtail/test/testapp/migrations/0035_modelwithcustommanager.py +30 -0
- wagtail/test/testapp/migrations/0036_complexdefaultstreampage.py +28 -0
- wagtail/test/testapp/models.py +79 -2
- wagtail/test/testapp/templates/tests/custom_docs_password_required.html +10 -0
- wagtail/test/testapp/templates/tests/custom_page_password_required.html +10 -0
- wagtail/test/testapp/views.py +24 -2
- wagtail/test/testapp/wagtail_hooks.py +19 -0
- wagtail/test/utils/wagtail_tests.py +2 -2
- wagtail/tests/test_blocks.py +262 -1
- wagtail/tests/test_migrations.py +1 -1
- wagtail/tests/test_page_model.py +77 -0
- wagtail/tests/test_page_privacy.py +18 -1
- wagtail/tests/test_rich_text.py +95 -5
- wagtail/tests/test_streamfield.py +43 -0
- wagtail/tests/test_utils.py +8 -2
- wagtail/tests/test_views.py +52 -1
- wagtail/tests/test_whitelist.py +7 -7
- wagtail/users/forms.py +3 -1
- wagtail/users/locale/en/LC_MESSAGES/django.po +124 -96
- wagtail/users/locale/fr/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/he_IL/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/he_IL/LC_MESSAGES/django.po +2 -2
- wagtail/users/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
- wagtail/users/locale/hr_HR/LC_MESSAGES/django.po +13 -2
- wagtail/users/migrations/0013_userprofile_density.py +23 -0
- wagtail/users/models.py +14 -3
- wagtail/users/templates/wagtailusers/groups/create.html +1 -7
- wagtail/users/templates/wagtailusers/groups/edit.html +1 -13
- wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +46 -2
- wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -3
- wagtail/users/templates/wagtailusers/users/create.html +1 -14
- wagtail/users/templates/wagtailusers/users/edit.html +1 -14
- wagtail/users/templates/wagtailusers/users/index.html +2 -5
- wagtail/users/templates/wagtailusers/users/index_results.html +3 -13
- wagtail/users/templates/wagtailusers/users/user_cell.html +9 -0
- wagtail/users/templatetags/wagtailusers_tags.py +107 -20
- wagtail/users/tests/test_admin_views.py +669 -90
- wagtail/users/views/groups.py +58 -61
- wagtail/users/views/users.py +211 -92
- wagtail/users/wagtail_hooks.py +6 -38
- wagtail/users/widgets.py +3 -5
- wagtail/utils/text.py +1 -1
- wagtail/views.py +5 -9
- wagtail/whitelist.py +1 -1
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/METADATA +5 -6
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/RECORD +496 -477
- wagtail/admin/static/wagtailadmin/js/page-editor.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/mousetrap.min.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/urlify.js +0 -1
- wagtail/admin/static/wagtailadmin/js/vendor/xregexp.min.js +0 -1
- wagtail/admin/templates/wagtailadmin/collections/index.html +0 -34
- wagtail/admin/templates/wagtailadmin/pages/revisions/_actions.html +0 -22
- wagtail/admin/templates/wagtailadmin/shared/page_breadcrumbs.html +0 -55
- wagtail/admin/tests/pages/test_dashboard.py +0 -172
- wagtail/contrib/redirects/templates/wagtailredirects/results.html +0 -23
- wagtail/documents/templates/wagtaildocs/documents/list.html +0 -2
- wagtail/search/tests/test_postgres_stemming.py +0 -40
- wagtail/sites/templates/wagtailsites/create.html +0 -7
- wagtail/sites/templates/wagtailsites/edit.html +0 -7
- wagtail/snippets/templates/wagtailsnippets/snippets/revisions/_actions.html +0 -36
- wagtail/users/templates/wagtailusers/users/list.html +0 -62
- wagtail/users/urls/users.py +0 -12
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.0.1.dist-info → wagtail-6.1rc1.dist-info}/top_level.txt +0 -0
wagtail/users/views/groups.py
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
+
from warnings import warn
|
|
2
|
+
|
|
1
3
|
from django.contrib.auth.models import Group
|
|
2
|
-
from django.
|
|
4
|
+
from django.shortcuts import get_object_or_404, redirect
|
|
5
|
+
from django.urls import re_path, reverse
|
|
6
|
+
from django.utils.functional import cached_property
|
|
7
|
+
from django.utils.translation import gettext
|
|
3
8
|
from django.utils.translation import gettext_lazy as _
|
|
4
9
|
|
|
5
10
|
from wagtail import hooks
|
|
6
11
|
from wagtail.admin.ui.tables import TitleColumn
|
|
12
|
+
from wagtail.admin.utils import set_query_params
|
|
7
13
|
from wagtail.admin.views import generic
|
|
8
14
|
from wagtail.admin.viewsets.model import ModelViewSet
|
|
15
|
+
from wagtail.admin.widgets.button import HeaderButton
|
|
9
16
|
from wagtail.users.forms import GroupForm, GroupPagePermissionFormSet
|
|
10
|
-
from wagtail.
|
|
17
|
+
from wagtail.utils.deprecation import RemovedInWagtail70Warning
|
|
11
18
|
|
|
12
19
|
_permission_panel_classes = None
|
|
13
20
|
|
|
@@ -45,11 +52,30 @@ class PermissionPanelFormsMixin:
|
|
|
45
52
|
for cls in get_permission_panel_classes()
|
|
46
53
|
]
|
|
47
54
|
|
|
55
|
+
def process_form(self):
|
|
56
|
+
form = self.get_form()
|
|
57
|
+
permission_panels = self.get_permission_panel_forms()
|
|
58
|
+
if form.is_valid() and all(panel.is_valid() for panel in permission_panels):
|
|
59
|
+
response = self.form_valid(form)
|
|
60
|
+
|
|
61
|
+
for panel in permission_panels:
|
|
62
|
+
panel.save()
|
|
63
|
+
|
|
64
|
+
return response
|
|
65
|
+
else:
|
|
66
|
+
return self.form_invalid(form)
|
|
67
|
+
|
|
48
68
|
def get_context_data(self, **kwargs):
|
|
49
69
|
if "permission_panels" not in kwargs:
|
|
50
70
|
kwargs["permission_panels"] = self.get_permission_panel_forms()
|
|
51
71
|
|
|
52
|
-
|
|
72
|
+
context = super().get_context_data(**kwargs)
|
|
73
|
+
|
|
74
|
+
# Add js/css media from the formsets to the existing media
|
|
75
|
+
for panel in context["permission_panels"]:
|
|
76
|
+
context["media"] += panel.media
|
|
77
|
+
|
|
78
|
+
return context
|
|
53
79
|
|
|
54
80
|
|
|
55
81
|
class IndexView(generic.IndexView):
|
|
@@ -74,9 +100,6 @@ class CreateView(PermissionPanelFormsMixin, generic.CreateView):
|
|
|
74
100
|
page_title = _("Add group")
|
|
75
101
|
success_message = _("Group '%(object)s' created.")
|
|
76
102
|
|
|
77
|
-
def get_page_subtitle(self):
|
|
78
|
-
return ""
|
|
79
|
-
|
|
80
103
|
def post(self, request, *args, **kwargs):
|
|
81
104
|
"""
|
|
82
105
|
Handle POST requests: instantiate a form instance with the passed
|
|
@@ -84,29 +107,7 @@ class CreateView(PermissionPanelFormsMixin, generic.CreateView):
|
|
|
84
107
|
"""
|
|
85
108
|
# Create an object now so that the permission panel forms have something to link them against
|
|
86
109
|
self.object = Group()
|
|
87
|
-
|
|
88
|
-
form = self.get_form()
|
|
89
|
-
permission_panels = self.get_permission_panel_forms()
|
|
90
|
-
if form.is_valid() and all(panel.is_valid() for panel in permission_panels):
|
|
91
|
-
response = self.form_valid(form)
|
|
92
|
-
|
|
93
|
-
for panel in permission_panels:
|
|
94
|
-
panel.save()
|
|
95
|
-
|
|
96
|
-
return response
|
|
97
|
-
else:
|
|
98
|
-
return self.form_invalid(form)
|
|
99
|
-
|
|
100
|
-
def get_context_data(self, **kwargs):
|
|
101
|
-
context = super().get_context_data(**kwargs)
|
|
102
|
-
|
|
103
|
-
# add a 'form_media' variable for the collected js/css media from the form and all formsets
|
|
104
|
-
form_media = context["form"].media
|
|
105
|
-
for panel in context["permission_panels"]:
|
|
106
|
-
form_media += panel.media
|
|
107
|
-
context["form_media"] = form_media
|
|
108
|
-
|
|
109
|
-
return context
|
|
110
|
+
return self.process_form()
|
|
110
111
|
|
|
111
112
|
|
|
112
113
|
class EditView(PermissionPanelFormsMixin, generic.EditView):
|
|
@@ -115,35 +116,26 @@ class EditView(PermissionPanelFormsMixin, generic.EditView):
|
|
|
115
116
|
delete_item_label = _("Delete group")
|
|
116
117
|
context_object_name = "group"
|
|
117
118
|
|
|
119
|
+
@cached_property
|
|
120
|
+
def header_buttons(self):
|
|
121
|
+
return [
|
|
122
|
+
HeaderButton(
|
|
123
|
+
gettext("View users in this group"),
|
|
124
|
+
url=set_query_params(
|
|
125
|
+
reverse("wagtailusers_users:index"),
|
|
126
|
+
{"group": self.object.pk},
|
|
127
|
+
),
|
|
128
|
+
icon_name="user",
|
|
129
|
+
)
|
|
130
|
+
]
|
|
131
|
+
|
|
118
132
|
def post(self, request, *args, **kwargs):
|
|
119
133
|
"""
|
|
120
134
|
Handle POST requests: instantiate a form instance with the passed
|
|
121
135
|
POST variables and then check if it's valid.
|
|
122
136
|
"""
|
|
123
137
|
self.object = self.get_object()
|
|
124
|
-
|
|
125
|
-
form = self.get_form()
|
|
126
|
-
permission_panels = self.get_permission_panel_forms()
|
|
127
|
-
if form.is_valid() and all(panel.is_valid() for panel in permission_panels):
|
|
128
|
-
response = self.form_valid(form)
|
|
129
|
-
|
|
130
|
-
for panel in permission_panels:
|
|
131
|
-
panel.save()
|
|
132
|
-
|
|
133
|
-
return response
|
|
134
|
-
else:
|
|
135
|
-
return self.form_invalid(form)
|
|
136
|
-
|
|
137
|
-
def get_context_data(self, **kwargs):
|
|
138
|
-
context = super().get_context_data(**kwargs)
|
|
139
|
-
|
|
140
|
-
# add a 'form_media' variable for the collected js/css media from the form and all formsets
|
|
141
|
-
form_media = context["form"].media
|
|
142
|
-
for panel in context["permission_panels"]:
|
|
143
|
-
form_media += panel.media
|
|
144
|
-
context["form_media"] = form_media
|
|
145
|
-
|
|
146
|
-
return context
|
|
138
|
+
return self.process_form()
|
|
147
139
|
|
|
148
140
|
|
|
149
141
|
class DeleteView(generic.DeleteView):
|
|
@@ -157,7 +149,6 @@ class GroupViewSet(ModelViewSet):
|
|
|
157
149
|
model = Group
|
|
158
150
|
ordering = ["name"]
|
|
159
151
|
add_to_reference_index = False
|
|
160
|
-
_show_breadcrumbs = False
|
|
161
152
|
|
|
162
153
|
index_view_class = IndexView
|
|
163
154
|
add_view_class = CreateView
|
|
@@ -168,16 +159,25 @@ class GroupViewSet(ModelViewSet):
|
|
|
168
159
|
|
|
169
160
|
@property
|
|
170
161
|
def users_view(self):
|
|
171
|
-
|
|
162
|
+
def view(request, pk):
|
|
163
|
+
legacy_url = reverse(self.get_url_name("users"), args=(pk,))
|
|
164
|
+
new_url = set_query_params(
|
|
165
|
+
reverse("wagtailusers_users:index"),
|
|
166
|
+
{"group": get_object_or_404(Group, pk=pk).pk},
|
|
167
|
+
)
|
|
172
168
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
169
|
+
warn(
|
|
170
|
+
f"Accessing the list of users in a group via {legacy_url} is "
|
|
171
|
+
f"deprecated, use {new_url} instead.",
|
|
172
|
+
RemovedInWagtail70Warning,
|
|
173
|
+
)
|
|
174
|
+
return redirect(new_url)
|
|
175
|
+
|
|
176
|
+
return view
|
|
176
177
|
|
|
177
178
|
def get_common_view_kwargs(self, **kwargs):
|
|
178
179
|
return super().get_common_view_kwargs(
|
|
179
180
|
**{
|
|
180
|
-
"history_url_name": None,
|
|
181
181
|
"usage_url_name": None,
|
|
182
182
|
**kwargs,
|
|
183
183
|
}
|
|
@@ -189,7 +189,4 @@ class GroupViewSet(ModelViewSet):
|
|
|
189
189
|
def get_urlpatterns(self):
|
|
190
190
|
return super().get_urlpatterns() + [
|
|
191
191
|
re_path(r"(\d+)/users/$", self.users_view, name="users"),
|
|
192
|
-
re_path(
|
|
193
|
-
r"(\d+)/users/results/$", self.users_results_view, name="users_results"
|
|
194
|
-
),
|
|
195
192
|
]
|
wagtail/users/views/users.py
CHANGED
|
@@ -1,18 +1,40 @@
|
|
|
1
|
+
from warnings import warn
|
|
2
|
+
|
|
3
|
+
import django_filters
|
|
1
4
|
from django.conf import settings
|
|
2
5
|
from django.contrib.auth import get_user_model, update_session_auth_hash
|
|
3
6
|
from django.contrib.auth.models import Group
|
|
4
|
-
from django.core.exceptions import PermissionDenied
|
|
7
|
+
from django.core.exceptions import FieldDoesNotExist, PermissionDenied
|
|
5
8
|
from django.db.models import Q
|
|
6
|
-
from django.
|
|
7
|
-
from django.
|
|
9
|
+
from django.forms import CheckboxSelectMultiple
|
|
10
|
+
from django.template import RequestContext
|
|
11
|
+
from django.utils.functional import cached_property
|
|
8
12
|
from django.utils.translation import gettext as _
|
|
9
13
|
from django.utils.translation import gettext_lazy
|
|
10
14
|
|
|
15
|
+
from wagtail import hooks
|
|
16
|
+
from wagtail.admin.filters import DateRangePickerWidget, WagtailFilterSet
|
|
17
|
+
from wagtail.admin.ui.tables import (
|
|
18
|
+
BulkActionsCheckboxColumn,
|
|
19
|
+
Column,
|
|
20
|
+
DateColumn,
|
|
21
|
+
StatusTagColumn,
|
|
22
|
+
TitleColumn,
|
|
23
|
+
)
|
|
24
|
+
from wagtail.admin.utils import get_user_display_name
|
|
11
25
|
from wagtail.admin.views.generic import CreateView, DeleteView, EditView, IndexView
|
|
26
|
+
from wagtail.admin.views.generic.history import HistoryView
|
|
27
|
+
from wagtail.admin.viewsets.model import ModelViewSet
|
|
28
|
+
from wagtail.admin.widgets.boolean_radio_select import BooleanRadioSelect
|
|
29
|
+
from wagtail.admin.widgets.button import (
|
|
30
|
+
BaseDropdownMenuButton,
|
|
31
|
+
ButtonWithDropdown,
|
|
32
|
+
)
|
|
12
33
|
from wagtail.compat import AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME
|
|
13
|
-
from wagtail.
|
|
34
|
+
from wagtail.coreutils import accepts_kwarg
|
|
14
35
|
from wagtail.users.forms import UserCreationForm, UserEditForm
|
|
15
36
|
from wagtail.users.utils import user_can_delete_user
|
|
37
|
+
from wagtail.utils.deprecation import RemovedInWagtail70Warning
|
|
16
38
|
from wagtail.utils.loading import get_custom_form
|
|
17
39
|
|
|
18
40
|
User = get_user_model()
|
|
@@ -64,6 +86,45 @@ def get_users_filter_query(q, model_fields):
|
|
|
64
86
|
return conditions
|
|
65
87
|
|
|
66
88
|
|
|
89
|
+
class UserColumn(TitleColumn):
|
|
90
|
+
cell_template_name = "wagtailusers/users/user_cell.html"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class UserFilterSet(WagtailFilterSet):
|
|
94
|
+
is_superuser = django_filters.BooleanFilter(
|
|
95
|
+
label=gettext_lazy("Administrator"),
|
|
96
|
+
widget=BooleanRadioSelect,
|
|
97
|
+
)
|
|
98
|
+
last_login = django_filters.DateFromToRangeFilter(
|
|
99
|
+
label=gettext_lazy("Last login"),
|
|
100
|
+
widget=DateRangePickerWidget,
|
|
101
|
+
)
|
|
102
|
+
group = django_filters.ModelMultipleChoiceFilter(
|
|
103
|
+
field_name="groups",
|
|
104
|
+
queryset=Group.objects.all(),
|
|
105
|
+
label=gettext_lazy("Group"),
|
|
106
|
+
widget=CheckboxSelectMultiple,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def __init__(self, data=None, queryset=None, *, request=None, prefix=None):
|
|
110
|
+
super().__init__(data, queryset, request=request, prefix=prefix)
|
|
111
|
+
try:
|
|
112
|
+
self._meta.model._meta.get_field("is_active")
|
|
113
|
+
except FieldDoesNotExist:
|
|
114
|
+
pass
|
|
115
|
+
else:
|
|
116
|
+
self.filters["is_active"] = django_filters.BooleanFilter(
|
|
117
|
+
field_name="is_active",
|
|
118
|
+
label=gettext_lazy("Active"),
|
|
119
|
+
widget=BooleanRadioSelect,
|
|
120
|
+
)
|
|
121
|
+
self.filters.move_to_end("is_active", last=False)
|
|
122
|
+
|
|
123
|
+
class Meta:
|
|
124
|
+
model = User
|
|
125
|
+
fields = []
|
|
126
|
+
|
|
127
|
+
|
|
67
128
|
class Index(IndexView):
|
|
68
129
|
"""
|
|
69
130
|
Lists the users for management within the admin.
|
|
@@ -71,72 +132,129 @@ class Index(IndexView):
|
|
|
71
132
|
|
|
72
133
|
template_name = "wagtailusers/users/index.html"
|
|
73
134
|
results_template_name = "wagtailusers/users/index_results.html"
|
|
74
|
-
|
|
75
|
-
permission_policy = ModelPermissionPolicy(User)
|
|
76
|
-
model = User
|
|
77
|
-
header_icon = "user"
|
|
78
|
-
add_item_label = _("Add a user")
|
|
135
|
+
add_item_label = gettext_lazy("Add a user")
|
|
79
136
|
context_object_name = "users"
|
|
80
|
-
index_url_name = "wagtailusers_users:index"
|
|
81
|
-
add_url_name = "wagtailusers_users:add"
|
|
82
|
-
edit_url_name = "wagtailusers_users:edit"
|
|
83
|
-
default_ordering = "name"
|
|
84
|
-
paginate_by = 20
|
|
85
137
|
is_searchable = True
|
|
86
138
|
page_title = gettext_lazy("Users")
|
|
87
139
|
show_other_searches = True
|
|
88
|
-
model_fields = [f.name for f in User._meta.get_fields()]
|
|
89
|
-
|
|
90
|
-
def setup(self, request, *args, **kwargs):
|
|
91
|
-
super().setup(request, *args, **kwargs)
|
|
92
|
-
self.group = get_object_or_404(Group, id=args[0]) if args else None
|
|
93
|
-
self.group_filter = Q(groups=self.group) if self.group else Q()
|
|
94
140
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
141
|
+
@cached_property
|
|
142
|
+
def columns(self):
|
|
143
|
+
_UserColumn = self._get_title_column_class(UserColumn)
|
|
144
|
+
return [
|
|
145
|
+
BulkActionsCheckboxColumn("bulk_actions", obj_type="user"),
|
|
146
|
+
_UserColumn(
|
|
147
|
+
"name",
|
|
148
|
+
accessor=lambda u: get_user_display_name(u),
|
|
149
|
+
label=gettext_lazy("Name"),
|
|
150
|
+
sort_key="name"
|
|
151
|
+
if self.model_fields.issuperset({"first_name", "last_name"})
|
|
152
|
+
else None,
|
|
153
|
+
get_url=self.get_edit_url,
|
|
154
|
+
classname="name",
|
|
155
|
+
),
|
|
156
|
+
Column(
|
|
157
|
+
self.model.USERNAME_FIELD,
|
|
158
|
+
accessor="get_username",
|
|
159
|
+
label=gettext_lazy("Username"),
|
|
160
|
+
sort_key=self.model.USERNAME_FIELD,
|
|
161
|
+
classname="username",
|
|
162
|
+
width="20%",
|
|
163
|
+
),
|
|
164
|
+
Column(
|
|
165
|
+
"is_superuser",
|
|
166
|
+
accessor=lambda u: gettext_lazy("Admin") if u.is_superuser else None,
|
|
167
|
+
label=gettext_lazy("Access level"),
|
|
168
|
+
sort_key="is_superuser",
|
|
169
|
+
classname="level",
|
|
170
|
+
width="10%",
|
|
171
|
+
),
|
|
172
|
+
StatusTagColumn(
|
|
173
|
+
"is_active",
|
|
174
|
+
accessor=lambda u: gettext_lazy("Active")
|
|
175
|
+
if u.is_active
|
|
176
|
+
else gettext_lazy("Inactive"),
|
|
177
|
+
primary=lambda u: u.is_active,
|
|
178
|
+
label=gettext_lazy("Status"),
|
|
179
|
+
sort_key="is_active" if "is_active" in self.model_fields else None,
|
|
180
|
+
classname="status",
|
|
181
|
+
width="10%",
|
|
182
|
+
),
|
|
183
|
+
DateColumn(
|
|
184
|
+
"last_login",
|
|
185
|
+
label=gettext_lazy("Last login"),
|
|
186
|
+
sort_key="last_login",
|
|
187
|
+
classname="last-login",
|
|
188
|
+
width="15%",
|
|
189
|
+
),
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
@cached_property
|
|
193
|
+
def model_fields(self):
|
|
194
|
+
return {f.name for f in User._meta.get_fields()}
|
|
195
|
+
|
|
196
|
+
def get_delete_url(self, instance):
|
|
197
|
+
if user_can_delete_user(self.request.user, instance):
|
|
198
|
+
return super().get_delete_url(instance)
|
|
199
|
+
|
|
200
|
+
def get_list_buttons(self, instance):
|
|
201
|
+
more_buttons = self.get_list_more_buttons(instance)
|
|
202
|
+
list_buttons = []
|
|
203
|
+
|
|
204
|
+
for hook in hooks.get_hooks("register_user_listing_buttons"):
|
|
205
|
+
if accepts_kwarg(hook, "request_user"):
|
|
206
|
+
hook_buttons = hook(user=instance, request_user=self.request.user)
|
|
207
|
+
else:
|
|
208
|
+
# old-style hook that accepts a context argument instead of request_user
|
|
209
|
+
hook_buttons = hook(RequestContext(self.request), instance)
|
|
210
|
+
warn(
|
|
211
|
+
"`register_user_listing_buttons` hook functions should accept a `request_user` argument instead of `context` -"
|
|
212
|
+
f" {hook.__module__}.{hook.__name__} needs to be updated",
|
|
213
|
+
category=RemovedInWagtail70Warning,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
for button in hook_buttons:
|
|
217
|
+
if isinstance(button, BaseDropdownMenuButton):
|
|
218
|
+
# If the button is a dropdown menu, add it to the top-level
|
|
219
|
+
# because we do not support nested dropdowns
|
|
220
|
+
list_buttons.append(button)
|
|
221
|
+
else:
|
|
222
|
+
# Otherwise, add it to the default "More" dropdown
|
|
223
|
+
more_buttons.append(button)
|
|
224
|
+
|
|
225
|
+
list_buttons.append(
|
|
226
|
+
ButtonWithDropdown(
|
|
227
|
+
buttons=sorted(more_buttons),
|
|
228
|
+
icon_name="dots-horizontal",
|
|
229
|
+
attrs={
|
|
230
|
+
"aria-label": _("More options for '%(title)s'")
|
|
231
|
+
% {"title": str(instance)},
|
|
232
|
+
},
|
|
233
|
+
)
|
|
234
|
+
)
|
|
100
235
|
|
|
101
|
-
|
|
102
|
-
return ["name", "username"]
|
|
236
|
+
return sorted(list_buttons)
|
|
103
237
|
|
|
104
|
-
def
|
|
105
|
-
|
|
106
|
-
if self.is_searching:
|
|
107
|
-
conditions = get_users_filter_query(self.search_query, model_fields)
|
|
108
|
-
users = User.objects.filter(self.group_filter & conditions)
|
|
109
|
-
else:
|
|
110
|
-
users = User.objects.filter(self.group_filter)
|
|
111
|
-
|
|
112
|
-
if self.locale:
|
|
113
|
-
users = users.filter(locale=self.locale)
|
|
238
|
+
def get_base_queryset(self):
|
|
239
|
+
users = User._default_manager.all()
|
|
114
240
|
|
|
115
|
-
if "wagtail_userprofile" in model_fields:
|
|
241
|
+
if "wagtail_userprofile" in self.model_fields:
|
|
116
242
|
users = users.select_related("wagtail_userprofile")
|
|
117
243
|
|
|
118
|
-
if "last_name" in model_fields and "first_name" in model_fields:
|
|
119
|
-
users = users.order_by("last_name", "first_name")
|
|
120
|
-
|
|
121
|
-
if self.ordering == "username":
|
|
122
|
-
users = users.order_by(User.USERNAME_FIELD)
|
|
123
|
-
|
|
124
244
|
return users
|
|
125
245
|
|
|
126
|
-
def
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
246
|
+
def order_queryset(self, queryset):
|
|
247
|
+
if self.ordering == "name":
|
|
248
|
+
return queryset.order_by("last_name", "first_name")
|
|
249
|
+
if self.ordering == "-name":
|
|
250
|
+
return queryset.order_by("-last_name", "-first_name")
|
|
251
|
+
return super().order_queryset(queryset)
|
|
132
252
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
)
|
|
139
|
-
return context_data
|
|
253
|
+
def search_queryset(self, queryset):
|
|
254
|
+
if self.is_searching:
|
|
255
|
+
conditions = get_users_filter_query(self.search_query, self.model_fields)
|
|
256
|
+
return queryset.filter(conditions)
|
|
257
|
+
return queryset
|
|
140
258
|
|
|
141
259
|
|
|
142
260
|
class Create(CreateView):
|
|
@@ -144,15 +262,6 @@ class Create(CreateView):
|
|
|
144
262
|
Provide the ability to create a user within the admin.
|
|
145
263
|
"""
|
|
146
264
|
|
|
147
|
-
permission_policy = ModelPermissionPolicy(User)
|
|
148
|
-
permission_required = "add"
|
|
149
|
-
model = User
|
|
150
|
-
form_class = get_user_creation_form()
|
|
151
|
-
template_name = "wagtailusers/users/create.html"
|
|
152
|
-
header_icon = "user"
|
|
153
|
-
add_url_name = "wagtailusers_users:add"
|
|
154
|
-
index_url_name = "wagtailusers_users:index"
|
|
155
|
-
edit_url_name = "wagtailusers_users:edit"
|
|
156
265
|
success_message = gettext_lazy("User '%(object)s' created.")
|
|
157
266
|
page_title = gettext_lazy("Add user")
|
|
158
267
|
|
|
@@ -169,25 +278,13 @@ class Create(CreateView):
|
|
|
169
278
|
self.object,
|
|
170
279
|
)
|
|
171
280
|
|
|
172
|
-
def get_add_url(self):
|
|
173
|
-
return None
|
|
174
|
-
|
|
175
281
|
|
|
176
282
|
class Edit(EditView):
|
|
177
283
|
"""
|
|
178
284
|
Provide the ability to edit a user within the admin.
|
|
179
285
|
"""
|
|
180
286
|
|
|
181
|
-
model = User
|
|
182
|
-
permission_policy = ModelPermissionPolicy(User)
|
|
183
|
-
form_class = get_user_edit_form()
|
|
184
|
-
header_icon = "user"
|
|
185
|
-
template_name = "wagtailusers/users/edit.html"
|
|
186
|
-
index_url_name = "wagtailusers_users:index"
|
|
187
|
-
edit_url_name = "wagtailusers_users:edit"
|
|
188
|
-
delete_url_name = "wagtailusers_users:delete"
|
|
189
287
|
success_message = gettext_lazy("User '%(object)s' updated.")
|
|
190
|
-
context_object_name = "user"
|
|
191
288
|
error_message = gettext_lazy("The user could not be saved due to errors.")
|
|
192
289
|
|
|
193
290
|
def setup(self, request, *args, **kwargs):
|
|
@@ -226,15 +323,11 @@ class Edit(EditView):
|
|
|
226
323
|
self.object,
|
|
227
324
|
)
|
|
228
325
|
|
|
229
|
-
def
|
|
230
|
-
return
|
|
231
|
-
|
|
232
|
-
def get_delete_url(self):
|
|
233
|
-
return reverse(self.delete_url_name, args=(self.object.pk,))
|
|
326
|
+
def get_page_subtitle(self):
|
|
327
|
+
return get_user_display_name(self.object)
|
|
234
328
|
|
|
235
329
|
def get_context_data(self, **kwargs):
|
|
236
330
|
context = super().get_context_data(**kwargs)
|
|
237
|
-
context.pop("action_url")
|
|
238
331
|
context["can_delete"] = self.can_delete
|
|
239
332
|
return context
|
|
240
333
|
|
|
@@ -244,15 +337,7 @@ class Delete(DeleteView):
|
|
|
244
337
|
Provide the ability to delete a user within the admin.
|
|
245
338
|
"""
|
|
246
339
|
|
|
247
|
-
permission_policy = ModelPermissionPolicy(User)
|
|
248
|
-
permission_required = "delete"
|
|
249
|
-
model = User
|
|
250
|
-
template_name = "wagtailusers/users/confirm_delete.html"
|
|
251
|
-
delete_url_name = "wagtailusers_users:delete"
|
|
252
|
-
edit_url_name = "wagtailusers_users:edit"
|
|
253
|
-
index_url_name = "wagtailusers_users:index"
|
|
254
340
|
page_title = gettext_lazy("Delete user")
|
|
255
|
-
context_object_name = "user"
|
|
256
341
|
success_message = gettext_lazy("User '%(object)s' deleted.")
|
|
257
342
|
|
|
258
343
|
def dispatch(self, request, *args, **kwargs):
|
|
@@ -274,3 +359,37 @@ class Delete(DeleteView):
|
|
|
274
359
|
self.request,
|
|
275
360
|
self.object,
|
|
276
361
|
)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
class History(HistoryView):
|
|
365
|
+
def get_page_subtitle(self):
|
|
366
|
+
return get_user_display_name(self.object)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class UserViewSet(ModelViewSet):
|
|
370
|
+
icon = "user"
|
|
371
|
+
model = User
|
|
372
|
+
ordering = "name"
|
|
373
|
+
add_to_reference_index = False
|
|
374
|
+
filterset_class = UserFilterSet
|
|
375
|
+
|
|
376
|
+
index_view_class = Index
|
|
377
|
+
add_view_class = Create
|
|
378
|
+
edit_view_class = Edit
|
|
379
|
+
delete_view_class = Delete
|
|
380
|
+
history_view_class = History
|
|
381
|
+
|
|
382
|
+
template_prefix = "wagtailusers/users/"
|
|
383
|
+
|
|
384
|
+
def get_common_view_kwargs(self, **kwargs):
|
|
385
|
+
return super().get_common_view_kwargs(
|
|
386
|
+
**{
|
|
387
|
+
"usage_url_name": None,
|
|
388
|
+
**kwargs,
|
|
389
|
+
}
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
def get_form_class(self, for_update=False):
|
|
393
|
+
if for_update:
|
|
394
|
+
return get_user_edit_form()
|
|
395
|
+
return get_user_creation_form()
|
wagtail/users/wagtail_hooks.py
CHANGED
|
@@ -3,7 +3,7 @@ from django.contrib.auth import get_user_model
|
|
|
3
3
|
from django.contrib.auth.models import Permission
|
|
4
4
|
from django.core.exceptions import ImproperlyConfigured
|
|
5
5
|
from django.db.models import Q
|
|
6
|
-
from django.urls import
|
|
6
|
+
from django.urls import reverse
|
|
7
7
|
from django.utils.module_loading import import_string
|
|
8
8
|
from django.utils.translation import gettext_lazy as _
|
|
9
9
|
|
|
@@ -14,24 +14,14 @@ from wagtail.admin.admin_url_finder import (
|
|
|
14
14
|
)
|
|
15
15
|
from wagtail.admin.menu import MenuItem
|
|
16
16
|
from wagtail.admin.search import SearchArea
|
|
17
|
-
from wagtail.admin.utils import get_user_display_name
|
|
18
17
|
from wagtail.compat import AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME
|
|
19
18
|
from wagtail.permission_policies import ModelPermissionPolicy
|
|
20
|
-
from wagtail.users.urls import users
|
|
21
|
-
from wagtail.users.utils import user_can_delete_user
|
|
22
19
|
from wagtail.users.views.bulk_actions import (
|
|
23
20
|
AssignRoleBulkAction,
|
|
24
21
|
DeleteBulkAction,
|
|
25
22
|
SetActiveStateBulkAction,
|
|
26
23
|
)
|
|
27
|
-
from wagtail.users.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@hooks.register("register_admin_urls")
|
|
31
|
-
def register_admin_urls():
|
|
32
|
-
return [
|
|
33
|
-
path("users/", include(users, namespace="wagtailusers_users")),
|
|
34
|
-
]
|
|
24
|
+
from wagtail.users.views.users import UserViewSet
|
|
35
25
|
|
|
36
26
|
|
|
37
27
|
def get_group_viewset_cls(app_config):
|
|
@@ -50,7 +40,10 @@ def get_group_viewset_cls(app_config):
|
|
|
50
40
|
def register_viewset():
|
|
51
41
|
app_config = apps.get_app_config("wagtailusers")
|
|
52
42
|
group_viewset_cls = get_group_viewset_cls(app_config)
|
|
53
|
-
return
|
|
43
|
+
return [
|
|
44
|
+
UserViewSet("wagtailusers_users", url_prefix="users"),
|
|
45
|
+
group_viewset_cls("wagtailusers_groups", url_prefix="groups"),
|
|
46
|
+
]
|
|
54
47
|
|
|
55
48
|
|
|
56
49
|
# Typically we would check the permission 'auth.change_user' (and 'auth.add_user' /
|
|
@@ -143,31 +136,6 @@ def register_users_search_area():
|
|
|
143
136
|
)
|
|
144
137
|
|
|
145
138
|
|
|
146
|
-
@hooks.register("register_user_listing_buttons")
|
|
147
|
-
def user_listing_buttons(context, user):
|
|
148
|
-
yield UserListingButton(
|
|
149
|
-
_("Edit"),
|
|
150
|
-
reverse("wagtailusers_users:edit", args=[user.pk]),
|
|
151
|
-
classname="button-secondary",
|
|
152
|
-
attrs={
|
|
153
|
-
"aria-label": _("Edit user '%(name)s'")
|
|
154
|
-
% {"name": get_user_display_name(user)}
|
|
155
|
-
},
|
|
156
|
-
priority=10,
|
|
157
|
-
)
|
|
158
|
-
if user_can_delete_user(context.request.user, user):
|
|
159
|
-
yield UserListingButton(
|
|
160
|
-
_("Delete"),
|
|
161
|
-
reverse("wagtailusers_users:delete", args=[user.pk]),
|
|
162
|
-
classname="no",
|
|
163
|
-
attrs={
|
|
164
|
-
"aria-label": _("Delete user '%(name)s'")
|
|
165
|
-
% {"name": get_user_display_name(user)}
|
|
166
|
-
},
|
|
167
|
-
priority=20,
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
|
|
171
139
|
User = get_user_model()
|
|
172
140
|
|
|
173
141
|
|
wagtail/users/widgets.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
from wagtail.admin.widgets import
|
|
1
|
+
from wagtail.admin.widgets import ListingButton
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
class UserListingButton(
|
|
5
|
-
|
|
6
|
-
classname = f"{classname} button button-small".strip()
|
|
7
|
-
super().__init__(label, url, classname=classname, **kwargs)
|
|
4
|
+
class UserListingButton(ListingButton):
|
|
5
|
+
pass
|
wagtail/utils/text.py
CHANGED