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.
Files changed (1125) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/copy_page.py +1 -1
  3. wagtail/actions/create_alias.py +1 -1
  4. wagtail/actions/delete_page.py +1 -1
  5. wagtail/actions/publish_page_revision.py +1 -1
  6. wagtail/actions/publish_revision.py +1 -1
  7. wagtail/actions/revert_to_page_revision.py +1 -1
  8. wagtail/actions/unpublish.py +1 -1
  9. wagtail/actions/unpublish_page.py +1 -1
  10. wagtail/admin/auth.py +3 -1
  11. wagtail/admin/checks.py +2 -2
  12. wagtail/admin/filters.py +28 -1
  13. wagtail/admin/forms/collections.py +1 -1
  14. wagtail/admin/forms/comments.py +1 -1
  15. wagtail/admin/forms/models.py +1 -1
  16. wagtail/admin/forms/pages.py +1 -1
  17. wagtail/admin/forms/tags.py +1 -1
  18. wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
  19. wagtail/admin/locale/ar/LC_MESSAGES/django.po +44 -89
  20. wagtail/admin/locale/az_AZ/LC_MESSAGES/django.mo +0 -0
  21. wagtail/admin/locale/az_AZ/LC_MESSAGES/django.po +4 -7
  22. wagtail/admin/locale/be/LC_MESSAGES/django.mo +0 -0
  23. wagtail/admin/locale/be/LC_MESSAGES/django.po +15 -42
  24. wagtail/admin/locale/bg/LC_MESSAGES/django.mo +0 -0
  25. wagtail/admin/locale/bg/LC_MESSAGES/django.po +7 -16
  26. wagtail/admin/locale/bn/LC_MESSAGES/django.mo +0 -0
  27. wagtail/admin/locale/bn/LC_MESSAGES/django.po +4 -13
  28. wagtail/admin/locale/ca/LC_MESSAGES/django.mo +0 -0
  29. wagtail/admin/locale/ca/LC_MESSAGES/django.po +159 -74
  30. wagtail/admin/locale/ca/LC_MESSAGES/djangojs.mo +0 -0
  31. wagtail/admin/locale/ca/LC_MESSAGES/djangojs.po +11 -0
  32. wagtail/admin/locale/cs/LC_MESSAGES/django.mo +0 -0
  33. wagtail/admin/locale/cs/LC_MESSAGES/django.po +40 -50
  34. wagtail/admin/locale/cy/LC_MESSAGES/django.mo +0 -0
  35. wagtail/admin/locale/cy/LC_MESSAGES/django.po +6 -13
  36. wagtail/admin/locale/da/LC_MESSAGES/django.mo +0 -0
  37. wagtail/admin/locale/da/LC_MESSAGES/django.po +10 -22
  38. wagtail/admin/locale/de/LC_MESSAGES/django.mo +0 -0
  39. wagtail/admin/locale/de/LC_MESSAGES/django.po +42 -93
  40. wagtail/admin/locale/dv/LC_MESSAGES/django.mo +0 -0
  41. wagtail/admin/locale/dv/LC_MESSAGES/django.po +26 -64
  42. wagtail/admin/locale/el/LC_MESSAGES/django.mo +0 -0
  43. wagtail/admin/locale/el/LC_MESSAGES/django.po +9 -31
  44. wagtail/admin/locale/en/LC_MESSAGES/django.po +278 -192
  45. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +29 -15
  46. wagtail/admin/locale/es/LC_MESSAGES/django.mo +0 -0
  47. wagtail/admin/locale/es/LC_MESSAGES/django.po +17 -52
  48. wagtail/admin/locale/es_419/LC_MESSAGES/django.mo +0 -0
  49. wagtail/admin/locale/es_419/LC_MESSAGES/django.po +4 -22
  50. wagtail/admin/locale/es_VE/LC_MESSAGES/django.mo +0 -0
  51. wagtail/admin/locale/es_VE/LC_MESSAGES/django.po +4 -7
  52. wagtail/admin/locale/et/LC_MESSAGES/django.mo +0 -0
  53. wagtail/admin/locale/et/LC_MESSAGES/django.po +15 -42
  54. wagtail/admin/locale/eu/LC_MESSAGES/django.po +1 -1
  55. wagtail/admin/locale/fa/LC_MESSAGES/django.mo +0 -0
  56. wagtail/admin/locale/fa/LC_MESSAGES/django.po +12 -50
  57. wagtail/admin/locale/fi/LC_MESSAGES/django.mo +0 -0
  58. wagtail/admin/locale/fi/LC_MESSAGES/django.po +43 -70
  59. wagtail/admin/locale/fi/LC_MESSAGES/djangojs.mo +0 -0
  60. wagtail/admin/locale/fi/LC_MESSAGES/djangojs.po +17 -0
  61. wagtail/admin/locale/fr/LC_MESSAGES/django.mo +0 -0
  62. wagtail/admin/locale/fr/LC_MESSAGES/django.po +157 -74
  63. wagtail/admin/locale/fr/LC_MESSAGES/djangojs.mo +0 -0
  64. wagtail/admin/locale/fr/LC_MESSAGES/djangojs.po +11 -0
  65. wagtail/admin/locale/gl/LC_MESSAGES/django.mo +0 -0
  66. wagtail/admin/locale/gl/LC_MESSAGES/django.po +155 -72
  67. wagtail/admin/locale/gl/LC_MESSAGES/djangojs.mo +0 -0
  68. wagtail/admin/locale/gl/LC_MESSAGES/djangojs.po +11 -0
  69. wagtail/admin/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  70. wagtail/admin/locale/he_IL/LC_MESSAGES/django.po +7 -28
  71. wagtail/admin/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  72. wagtail/admin/locale/hr_HR/LC_MESSAGES/django.po +15 -38
  73. wagtail/admin/locale/ht/LC_MESSAGES/django.po +4 -4
  74. wagtail/admin/locale/hu/LC_MESSAGES/django.mo +0 -0
  75. wagtail/admin/locale/hu/LC_MESSAGES/django.po +44 -91
  76. wagtail/admin/locale/id_ID/LC_MESSAGES/django.mo +0 -0
  77. wagtail/admin/locale/id_ID/LC_MESSAGES/django.po +10 -31
  78. wagtail/admin/locale/is_IS/LC_MESSAGES/django.mo +0 -0
  79. wagtail/admin/locale/is_IS/LC_MESSAGES/django.po +41 -87
  80. wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
  81. wagtail/admin/locale/it/LC_MESSAGES/django.po +34 -78
  82. wagtail/admin/locale/ja/LC_MESSAGES/django.mo +0 -0
  83. wagtail/admin/locale/ja/LC_MESSAGES/django.po +15 -42
  84. wagtail/admin/locale/ka/LC_MESSAGES/django.po +4 -4
  85. wagtail/admin/locale/ko/LC_MESSAGES/django.mo +0 -0
  86. wagtail/admin/locale/ko/LC_MESSAGES/django.po +20 -57
  87. wagtail/admin/locale/lt/LC_MESSAGES/django.mo +0 -0
  88. wagtail/admin/locale/lt/LC_MESSAGES/django.po +12 -31
  89. wagtail/admin/locale/lv/LC_MESSAGES/django.mo +0 -0
  90. wagtail/admin/locale/lv/LC_MESSAGES/django.po +9 -40
  91. wagtail/admin/locale/mi/LC_MESSAGES/django.mo +0 -0
  92. wagtail/admin/locale/mi/LC_MESSAGES/django.po +6 -10
  93. wagtail/admin/locale/mn/LC_MESSAGES/django.mo +0 -0
  94. wagtail/admin/locale/mn/LC_MESSAGES/django.po +10 -43
  95. wagtail/admin/locale/my/LC_MESSAGES/django.po +4 -4
  96. wagtail/admin/locale/nb/LC_MESSAGES/django.mo +0 -0
  97. wagtail/admin/locale/nb/LC_MESSAGES/django.po +15 -53
  98. wagtail/admin/locale/nl/LC_MESSAGES/django.mo +0 -0
  99. wagtail/admin/locale/nl/LC_MESSAGES/django.po +208 -70
  100. wagtail/admin/locale/nl/LC_MESSAGES/djangojs.mo +0 -0
  101. wagtail/admin/locale/nl/LC_MESSAGES/djangojs.po +19 -2
  102. wagtail/admin/locale/pl/LC_MESSAGES/django.mo +0 -0
  103. wagtail/admin/locale/pl/LC_MESSAGES/django.po +27 -72
  104. wagtail/admin/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  105. wagtail/admin/locale/pt_BR/LC_MESSAGES/django.po +38 -83
  106. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  107. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +17 -56
  108. wagtail/admin/locale/ro/LC_MESSAGES/django.mo +0 -0
  109. wagtail/admin/locale/ro/LC_MESSAGES/django.po +23 -68
  110. wagtail/admin/locale/ru/LC_MESSAGES/django.mo +0 -0
  111. wagtail/admin/locale/ru/LC_MESSAGES/django.po +96 -84
  112. wagtail/admin/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  113. wagtail/admin/locale/sk_SK/LC_MESSAGES/django.po +9 -28
  114. wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
  115. wagtail/admin/locale/sl/LC_MESSAGES/django.po +45 -90
  116. wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
  117. wagtail/admin/locale/sv/LC_MESSAGES/django.po +27 -72
  118. wagtail/admin/locale/tet/LC_MESSAGES/django.mo +0 -0
  119. wagtail/admin/locale/tet/LC_MESSAGES/django.po +12 -22
  120. wagtail/admin/locale/th/LC_MESSAGES/django.mo +0 -0
  121. wagtail/admin/locale/th/LC_MESSAGES/django.po +10 -42
  122. wagtail/admin/locale/tr/LC_MESSAGES/django.mo +0 -0
  123. wagtail/admin/locale/tr/LC_MESSAGES/django.po +64 -70
  124. wagtail/admin/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
  125. wagtail/admin/locale/tr_TR/LC_MESSAGES/django.po +15 -42
  126. wagtail/admin/locale/ug/LC_MESSAGES/django.mo +0 -0
  127. wagtail/admin/locale/ug/LC_MESSAGES/django.po +38 -83
  128. wagtail/admin/locale/uk/LC_MESSAGES/django.mo +0 -0
  129. wagtail/admin/locale/uk/LC_MESSAGES/django.po +15 -45
  130. wagtail/admin/locale/vi/LC_MESSAGES/django.mo +0 -0
  131. wagtail/admin/locale/vi/LC_MESSAGES/django.po +4 -17
  132. wagtail/admin/locale/zh/LC_MESSAGES/django.mo +0 -0
  133. wagtail/admin/locale/zh/LC_MESSAGES/django.po +7 -19
  134. wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  135. wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.po +17 -54
  136. wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
  137. wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.po +15 -37
  138. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  139. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  140. wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
  141. wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
  142. wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
  143. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  144. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  145. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +2 -2
  146. wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
  147. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  148. wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
  149. wagtail/admin/static/wagtailadmin/js/icons.js +1 -1
  150. wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
  151. wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
  152. wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
  153. wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
  154. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  155. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  156. wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
  157. wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
  158. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  159. wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
  160. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  161. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  162. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +2 -2
  163. wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-modal.js +1 -1
  164. wagtail/admin/static/wagtailadmin/js/vendor/bootstrap-transition.js +1 -1
  165. wagtail/admin/static/wagtailadmin/js/vendor/jquery-3.6.0.min.js +1 -1
  166. wagtail/admin/static/wagtailadmin/js/vendor/jquery-ui-1.13.2.min.js +1 -1
  167. wagtail/admin/static/wagtailadmin/js/vendor/jquery.datetimepicker.js +1 -1
  168. wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload-process.js +1 -1
  169. wagtail/admin/static/wagtailadmin/js/vendor/jquery.fileupload.js +1 -1
  170. wagtail/admin/static/wagtailadmin/js/vendor/jquery.iframe-transport.js +1 -1
  171. wagtail/admin/static/wagtailadmin/js/vendor/tag-it.js +1 -1
  172. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  173. wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +1 -1
  174. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  175. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  176. wagtail/admin/templates/wagtailadmin/account/account.html +2 -0
  177. wagtail/admin/templates/wagtailadmin/base.html +14 -0
  178. wagtail/admin/templates/wagtailadmin/generic/chooser/chooser.html +2 -1
  179. wagtail/admin/templates/wagtailadmin/generic/chooser/creation_form.html +2 -1
  180. wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
  181. wagtail/admin/templates/wagtailadmin/panels/object_list.html +1 -1
  182. wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +3 -2
  183. wagtail/admin/templates/wagtailadmin/shared/formatted_field.html +1 -1
  184. wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
  185. wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +19 -0
  186. wagtail/admin/templates/wagtailadmin/shared/panel.html +1 -1
  187. wagtail/admin/templates/wagtailadmin/shared/set_privacy.html +15 -0
  188. wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +28 -1
  189. wagtail/admin/templates/wagtailadmin/shared/workflow_history/detail.html +2 -2
  190. wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_header.html → tables/ordering_header.html} +2 -2
  191. wagtail/admin/templates/wagtailadmin/tables/title_cell.html +1 -1
  192. wagtail/admin/templates/wagtailadmin/widgets/{daterange_input.html → range_input.html} +1 -1
  193. wagtail/admin/templates/wagtailadmin/workflows/task_chooser/chooser.html +4 -2
  194. wagtail/admin/templatetags/wagtailadmin_tags.py +41 -22
  195. wagtail/admin/tests/api/test_pages.py +7 -7
  196. wagtail/admin/tests/api/test_renderer_classes.py +16 -0
  197. wagtail/admin/tests/pages/test_create_page.py +42 -2
  198. wagtail/admin/tests/pages/test_edit_page.py +128 -14
  199. wagtail/admin/tests/pages/test_explorer_view.py +34 -7
  200. wagtail/admin/tests/pages/test_reorder_page.py +11 -0
  201. wagtail/admin/tests/test_collections_views.py +12 -0
  202. wagtail/admin/tests/test_edit_handlers.py +3 -3
  203. wagtail/admin/tests/test_filters.py +2 -2
  204. wagtail/admin/tests/test_keyboard_shortcuts.py +52 -2
  205. wagtail/admin/tests/test_menu.py +0 -2
  206. wagtail/admin/tests/test_privacy.py +16 -16
  207. wagtail/admin/tests/test_templatetags.py +137 -0
  208. wagtail/admin/tests/test_workflows.py +34 -0
  209. wagtail/admin/tests/viewsets/test_model_viewset.py +322 -0
  210. wagtail/admin/ui/tables/orderable.py +73 -0
  211. wagtail/admin/ui/tables/pages.py +3 -13
  212. wagtail/admin/views/collection_privacy.py +6 -2
  213. wagtail/admin/views/generic/__init__.py +1 -0
  214. wagtail/admin/views/generic/mixins.py +20 -2
  215. wagtail/admin/views/generic/models.py +67 -1
  216. wagtail/admin/views/generic/ordering.py +79 -0
  217. wagtail/admin/views/home.py +3 -3
  218. wagtail/admin/views/page_privacy.py +5 -2
  219. wagtail/admin/views/pages/create.py +1 -1
  220. wagtail/admin/views/pages/edit.py +2 -2
  221. wagtail/admin/views/pages/listing.py +7 -42
  222. wagtail/admin/views/pages/move.py +1 -1
  223. wagtail/admin/views/pages/ordering.py +1 -1
  224. wagtail/admin/viewsets/base.py +1 -1
  225. wagtail/admin/viewsets/model.py +49 -1
  226. wagtail/admin/wagtail_hooks.py +2 -1
  227. wagtail/admin/widgets/slug.py +10 -10
  228. wagtail/api/v2/serializers.py +1 -1
  229. wagtail/api/v2/tests/test_renderer_classes.py +32 -0
  230. wagtail/apps.py +2 -0
  231. wagtail/bin/wagtail.py +1 -1
  232. wagtail/contrib/forms/locale/af/LC_MESSAGES/django.po +1 -1
  233. wagtail/contrib/forms/locale/ar/LC_MESSAGES/django.po +1 -1
  234. wagtail/contrib/forms/locale/az_AZ/LC_MESSAGES/django.po +1 -1
  235. wagtail/contrib/forms/locale/be/LC_MESSAGES/django.po +1 -1
  236. wagtail/contrib/forms/locale/bg/LC_MESSAGES/django.po +1 -1
  237. wagtail/contrib/forms/locale/bn/LC_MESSAGES/django.po +1 -1
  238. wagtail/contrib/forms/locale/ca/LC_MESSAGES/django.po +1 -1
  239. wagtail/contrib/forms/locale/cs/LC_MESSAGES/django.po +1 -1
  240. wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.po +1 -1
  241. wagtail/contrib/forms/locale/da/LC_MESSAGES/django.po +1 -1
  242. wagtail/contrib/forms/locale/de/LC_MESSAGES/django.po +1 -1
  243. wagtail/contrib/forms/locale/dv/LC_MESSAGES/django.po +1 -1
  244. wagtail/contrib/forms/locale/el/LC_MESSAGES/django.po +1 -1
  245. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +14 -14
  246. wagtail/contrib/forms/locale/es/LC_MESSAGES/django.po +1 -1
  247. wagtail/contrib/forms/locale/es_419/LC_MESSAGES/django.po +1 -1
  248. wagtail/contrib/forms/locale/et/LC_MESSAGES/django.po +1 -1
  249. wagtail/contrib/forms/locale/eu/LC_MESSAGES/django.po +1 -1
  250. wagtail/contrib/forms/locale/fa/LC_MESSAGES/django.po +1 -1
  251. wagtail/contrib/forms/locale/fi/LC_MESSAGES/django.po +1 -1
  252. wagtail/contrib/forms/locale/fr/LC_MESSAGES/django.po +1 -1
  253. wagtail/contrib/forms/locale/gl/LC_MESSAGES/django.po +1 -1
  254. wagtail/contrib/forms/locale/he_IL/LC_MESSAGES/django.po +1 -1
  255. wagtail/contrib/forms/locale/hr_HR/LC_MESSAGES/django.po +1 -1
  256. wagtail/contrib/forms/locale/ht/LC_MESSAGES/django.po +1 -1
  257. wagtail/contrib/forms/locale/hu/LC_MESSAGES/django.po +1 -1
  258. wagtail/contrib/forms/locale/hy/LC_MESSAGES/django.po +1 -1
  259. wagtail/contrib/forms/locale/id_ID/LC_MESSAGES/django.po +1 -1
  260. wagtail/contrib/forms/locale/is_IS/LC_MESSAGES/django.po +1 -1
  261. wagtail/contrib/forms/locale/it/LC_MESSAGES/django.po +1 -1
  262. wagtail/contrib/forms/locale/ja/LC_MESSAGES/django.po +1 -1
  263. wagtail/contrib/forms/locale/ka/LC_MESSAGES/django.po +1 -1
  264. wagtail/contrib/forms/locale/ko/LC_MESSAGES/django.po +1 -1
  265. wagtail/contrib/forms/locale/lt/LC_MESSAGES/django.po +1 -1
  266. wagtail/contrib/forms/locale/lv/LC_MESSAGES/django.po +1 -1
  267. wagtail/contrib/forms/locale/mi/LC_MESSAGES/django.po +1 -1
  268. wagtail/contrib/forms/locale/mn/LC_MESSAGES/django.po +1 -1
  269. wagtail/contrib/forms/locale/my/LC_MESSAGES/django.po +1 -1
  270. wagtail/contrib/forms/locale/nb/LC_MESSAGES/django.po +1 -1
  271. wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.mo +0 -0
  272. wagtail/contrib/forms/locale/nl/LC_MESSAGES/django.po +20 -3
  273. wagtail/contrib/forms/locale/pl/LC_MESSAGES/django.po +1 -1
  274. wagtail/contrib/forms/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  275. wagtail/contrib/forms/locale/pt_PT/LC_MESSAGES/django.po +1 -1
  276. wagtail/contrib/forms/locale/ro/LC_MESSAGES/django.po +1 -1
  277. wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.mo +0 -0
  278. wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.po +19 -2
  279. wagtail/contrib/forms/locale/sk_SK/LC_MESSAGES/django.po +1 -1
  280. wagtail/contrib/forms/locale/sl/LC_MESSAGES/django.po +1 -1
  281. wagtail/contrib/forms/locale/sv/LC_MESSAGES/django.po +1 -1
  282. wagtail/contrib/forms/locale/tet/LC_MESSAGES/django.po +1 -1
  283. wagtail/contrib/forms/locale/th/LC_MESSAGES/django.po +1 -1
  284. wagtail/contrib/forms/locale/tr/LC_MESSAGES/django.mo +0 -0
  285. wagtail/contrib/forms/locale/tr/LC_MESSAGES/django.po +12 -2
  286. wagtail/contrib/forms/locale/tr_TR/LC_MESSAGES/django.po +1 -1
  287. wagtail/contrib/forms/locale/ug/LC_MESSAGES/django.po +1 -1
  288. wagtail/contrib/forms/locale/uk/LC_MESSAGES/django.po +1 -1
  289. wagtail/contrib/forms/locale/vi/LC_MESSAGES/django.po +1 -1
  290. wagtail/contrib/forms/locale/zh/LC_MESSAGES/django.po +1 -1
  291. wagtail/contrib/forms/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
  292. wagtail/contrib/forms/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
  293. wagtail/contrib/frontend_cache/tests.py +4 -2
  294. wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.mo +0 -0
  295. wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.po +1 -13
  296. wagtail/contrib/redirects/locale/be/LC_MESSAGES/django.po +1 -1
  297. wagtail/contrib/redirects/locale/bg/LC_MESSAGES/django.po +1 -1
  298. wagtail/contrib/redirects/locale/bn/LC_MESSAGES/django.po +1 -1
  299. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.mo +0 -0
  300. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +9 -10
  301. wagtail/contrib/redirects/locale/cs/LC_MESSAGES/django.mo +0 -0
  302. wagtail/contrib/redirects/locale/cs/LC_MESSAGES/django.po +1 -13
  303. wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.mo +0 -0
  304. wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.po +1 -13
  305. wagtail/contrib/redirects/locale/da/LC_MESSAGES/django.po +1 -1
  306. wagtail/contrib/redirects/locale/de/LC_MESSAGES/django.mo +0 -0
  307. wagtail/contrib/redirects/locale/de/LC_MESSAGES/django.po +1 -13
  308. wagtail/contrib/redirects/locale/dv/LC_MESSAGES/django.po +1 -1
  309. wagtail/contrib/redirects/locale/el/LC_MESSAGES/django.po +1 -1
  310. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +4 -4
  311. wagtail/contrib/redirects/locale/en_IN/LC_MESSAGES/django.po +1 -1
  312. wagtail/contrib/redirects/locale/es/LC_MESSAGES/django.mo +0 -0
  313. wagtail/contrib/redirects/locale/es/LC_MESSAGES/django.po +1 -14
  314. wagtail/contrib/redirects/locale/es_419/LC_MESSAGES/django.po +1 -1
  315. wagtail/contrib/redirects/locale/es_VE/LC_MESSAGES/django.po +1 -1
  316. wagtail/contrib/redirects/locale/et/LC_MESSAGES/django.mo +0 -0
  317. wagtail/contrib/redirects/locale/et/LC_MESSAGES/django.po +1 -13
  318. wagtail/contrib/redirects/locale/eu/LC_MESSAGES/django.po +1 -1
  319. wagtail/contrib/redirects/locale/fa/LC_MESSAGES/django.po +1 -1
  320. wagtail/contrib/redirects/locale/fi/LC_MESSAGES/django.mo +0 -0
  321. wagtail/contrib/redirects/locale/fi/LC_MESSAGES/django.po +7 -11
  322. wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.mo +0 -0
  323. wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.po +9 -8
  324. wagtail/contrib/redirects/locale/gl/LC_MESSAGES/django.mo +0 -0
  325. wagtail/contrib/redirects/locale/gl/LC_MESSAGES/django.po +9 -9
  326. wagtail/contrib/redirects/locale/he_IL/LC_MESSAGES/django.po +1 -1
  327. wagtail/contrib/redirects/locale/hi/LC_MESSAGES/django.po +1 -1
  328. wagtail/contrib/redirects/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  329. wagtail/contrib/redirects/locale/hr_HR/LC_MESSAGES/django.po +1 -13
  330. wagtail/contrib/redirects/locale/ht/LC_MESSAGES/django.po +1 -1
  331. wagtail/contrib/redirects/locale/hu/LC_MESSAGES/django.mo +0 -0
  332. wagtail/contrib/redirects/locale/hu/LC_MESSAGES/django.po +1 -13
  333. wagtail/contrib/redirects/locale/hy/LC_MESSAGES/django.po +1 -1
  334. wagtail/contrib/redirects/locale/id_ID/LC_MESSAGES/django.po +1 -1
  335. wagtail/contrib/redirects/locale/is_IS/LC_MESSAGES/django.mo +0 -0
  336. wagtail/contrib/redirects/locale/is_IS/LC_MESSAGES/django.po +1 -13
  337. wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.mo +0 -0
  338. wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.po +1 -14
  339. wagtail/contrib/redirects/locale/ja/LC_MESSAGES/django.mo +0 -0
  340. wagtail/contrib/redirects/locale/ja/LC_MESSAGES/django.po +1 -13
  341. wagtail/contrib/redirects/locale/ka/LC_MESSAGES/django.po +1 -1
  342. wagtail/contrib/redirects/locale/ko/LC_MESSAGES/django.po +1 -1
  343. wagtail/contrib/redirects/locale/lt/LC_MESSAGES/django.po +1 -1
  344. wagtail/contrib/redirects/locale/lv/LC_MESSAGES/django.po +1 -1
  345. wagtail/contrib/redirects/locale/mi/LC_MESSAGES/django.po +1 -1
  346. wagtail/contrib/redirects/locale/mn/LC_MESSAGES/django.po +1 -1
  347. wagtail/contrib/redirects/locale/my/LC_MESSAGES/django.po +1 -1
  348. wagtail/contrib/redirects/locale/nb/LC_MESSAGES/django.mo +0 -0
  349. wagtail/contrib/redirects/locale/nb/LC_MESSAGES/django.po +1 -13
  350. wagtail/contrib/redirects/locale/nl/LC_MESSAGES/django.mo +0 -0
  351. wagtail/contrib/redirects/locale/nl/LC_MESSAGES/django.po +9 -9
  352. wagtail/contrib/redirects/locale/pl/LC_MESSAGES/django.mo +0 -0
  353. wagtail/contrib/redirects/locale/pl/LC_MESSAGES/django.po +1 -14
  354. wagtail/contrib/redirects/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  355. wagtail/contrib/redirects/locale/pt_BR/LC_MESSAGES/django.po +1 -13
  356. wagtail/contrib/redirects/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  357. wagtail/contrib/redirects/locale/pt_PT/LC_MESSAGES/django.po +1 -13
  358. wagtail/contrib/redirects/locale/ro/LC_MESSAGES/django.mo +0 -0
  359. wagtail/contrib/redirects/locale/ro/LC_MESSAGES/django.po +1 -13
  360. wagtail/contrib/redirects/locale/ru/LC_MESSAGES/django.mo +0 -0
  361. wagtail/contrib/redirects/locale/ru/LC_MESSAGES/django.po +1 -13
  362. wagtail/contrib/redirects/locale/sk_SK/LC_MESSAGES/django.po +1 -1
  363. wagtail/contrib/redirects/locale/sl/LC_MESSAGES/django.mo +0 -0
  364. wagtail/contrib/redirects/locale/sl/LC_MESSAGES/django.po +1 -14
  365. wagtail/contrib/redirects/locale/sr/LC_MESSAGES/django.po +1 -1
  366. wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.mo +0 -0
  367. wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.po +1 -13
  368. wagtail/contrib/redirects/locale/ta/LC_MESSAGES/django.po +1 -1
  369. wagtail/contrib/redirects/locale/tet/LC_MESSAGES/django.po +1 -1
  370. wagtail/contrib/redirects/locale/th/LC_MESSAGES/django.po +1 -1
  371. wagtail/contrib/redirects/locale/tr/LC_MESSAGES/django.mo +0 -0
  372. wagtail/contrib/redirects/locale/tr/LC_MESSAGES/django.po +1 -13
  373. wagtail/contrib/redirects/locale/tr_TR/LC_MESSAGES/django.po +1 -1
  374. wagtail/contrib/redirects/locale/ug/LC_MESSAGES/django.mo +0 -0
  375. wagtail/contrib/redirects/locale/ug/LC_MESSAGES/django.po +1 -13
  376. wagtail/contrib/redirects/locale/uk/LC_MESSAGES/django.mo +0 -0
  377. wagtail/contrib/redirects/locale/uk/LC_MESSAGES/django.po +1 -13
  378. wagtail/contrib/redirects/locale/vi/LC_MESSAGES/django.po +1 -1
  379. wagtail/contrib/redirects/locale/zh/LC_MESSAGES/django.po +1 -1
  380. wagtail/contrib/redirects/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  381. wagtail/contrib/redirects/locale/zh_Hans/LC_MESSAGES/django.po +1 -13
  382. wagtail/contrib/redirects/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
  383. wagtail/contrib/redirects/tests/test_tmp_storages.py +20 -0
  384. wagtail/contrib/redirects/tmp_storages.py +1 -1
  385. wagtail/contrib/redirects/views.py +3 -3
  386. wagtail/contrib/search_promotions/locale/af/LC_MESSAGES/django.po +1 -1
  387. wagtail/contrib/search_promotions/locale/ar/LC_MESSAGES/django.mo +0 -0
  388. wagtail/contrib/search_promotions/locale/ar/LC_MESSAGES/django.po +1 -7
  389. wagtail/contrib/search_promotions/locale/az_AZ/LC_MESSAGES/django.po +1 -1
  390. wagtail/contrib/search_promotions/locale/be/LC_MESSAGES/django.mo +0 -0
  391. wagtail/contrib/search_promotions/locale/be/LC_MESSAGES/django.po +1 -7
  392. wagtail/contrib/search_promotions/locale/bg/LC_MESSAGES/django.po +1 -1
  393. wagtail/contrib/search_promotions/locale/bn/LC_MESSAGES/django.po +1 -1
  394. wagtail/contrib/search_promotions/locale/ca/LC_MESSAGES/django.mo +0 -0
  395. wagtail/contrib/search_promotions/locale/ca/LC_MESSAGES/django.po +5 -5
  396. wagtail/contrib/search_promotions/locale/cs/LC_MESSAGES/django.mo +0 -0
  397. wagtail/contrib/search_promotions/locale/cs/LC_MESSAGES/django.po +1 -7
  398. wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.mo +0 -0
  399. wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.po +1 -7
  400. wagtail/contrib/search_promotions/locale/da/LC_MESSAGES/django.po +1 -1
  401. wagtail/contrib/search_promotions/locale/de/LC_MESSAGES/django.mo +0 -0
  402. wagtail/contrib/search_promotions/locale/de/LC_MESSAGES/django.po +1 -7
  403. wagtail/contrib/search_promotions/locale/dv/LC_MESSAGES/django.po +1 -1
  404. wagtail/contrib/search_promotions/locale/el/LC_MESSAGES/django.mo +0 -0
  405. wagtail/contrib/search_promotions/locale/el/LC_MESSAGES/django.po +1 -7
  406. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +3 -3
  407. wagtail/contrib/search_promotions/locale/es/LC_MESSAGES/django.mo +0 -0
  408. wagtail/contrib/search_promotions/locale/es/LC_MESSAGES/django.po +1 -7
  409. wagtail/contrib/search_promotions/locale/es_419/LC_MESSAGES/django.po +1 -1
  410. wagtail/contrib/search_promotions/locale/et/LC_MESSAGES/django.mo +0 -0
  411. wagtail/contrib/search_promotions/locale/et/LC_MESSAGES/django.po +1 -7
  412. wagtail/contrib/search_promotions/locale/eu/LC_MESSAGES/django.po +1 -1
  413. wagtail/contrib/search_promotions/locale/fa/LC_MESSAGES/django.mo +0 -0
  414. wagtail/contrib/search_promotions/locale/fa/LC_MESSAGES/django.po +1 -7
  415. wagtail/contrib/search_promotions/locale/fi/LC_MESSAGES/django.mo +0 -0
  416. wagtail/contrib/search_promotions/locale/fi/LC_MESSAGES/django.po +1 -7
  417. wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.mo +0 -0
  418. wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.po +5 -5
  419. wagtail/contrib/search_promotions/locale/gl/LC_MESSAGES/django.mo +0 -0
  420. wagtail/contrib/search_promotions/locale/gl/LC_MESSAGES/django.po +5 -5
  421. wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  422. wagtail/contrib/search_promotions/locale/he_IL/LC_MESSAGES/django.po +1 -7
  423. wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  424. wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.po +1 -7
  425. wagtail/contrib/search_promotions/locale/ht/LC_MESSAGES/django.po +1 -1
  426. wagtail/contrib/search_promotions/locale/hu/LC_MESSAGES/django.mo +0 -0
  427. wagtail/contrib/search_promotions/locale/hu/LC_MESSAGES/django.po +1 -7
  428. wagtail/contrib/search_promotions/locale/id_ID/LC_MESSAGES/django.mo +0 -0
  429. wagtail/contrib/search_promotions/locale/id_ID/LC_MESSAGES/django.po +1 -7
  430. wagtail/contrib/search_promotions/locale/is_IS/LC_MESSAGES/django.mo +0 -0
  431. wagtail/contrib/search_promotions/locale/is_IS/LC_MESSAGES/django.po +1 -7
  432. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
  433. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +1 -7
  434. wagtail/contrib/search_promotions/locale/ja/LC_MESSAGES/django.mo +0 -0
  435. wagtail/contrib/search_promotions/locale/ja/LC_MESSAGES/django.po +1 -7
  436. wagtail/contrib/search_promotions/locale/ka/LC_MESSAGES/django.po +1 -1
  437. wagtail/contrib/search_promotions/locale/ko/LC_MESSAGES/django.mo +0 -0
  438. wagtail/contrib/search_promotions/locale/ko/LC_MESSAGES/django.po +1 -7
  439. wagtail/contrib/search_promotions/locale/lt/LC_MESSAGES/django.mo +0 -0
  440. wagtail/contrib/search_promotions/locale/lt/LC_MESSAGES/django.po +1 -7
  441. wagtail/contrib/search_promotions/locale/lv/LC_MESSAGES/django.mo +0 -0
  442. wagtail/contrib/search_promotions/locale/lv/LC_MESSAGES/django.po +1 -7
  443. wagtail/contrib/search_promotions/locale/mi/LC_MESSAGES/django.po +1 -1
  444. wagtail/contrib/search_promotions/locale/mn/LC_MESSAGES/django.po +1 -1
  445. wagtail/contrib/search_promotions/locale/my/LC_MESSAGES/django.po +1 -1
  446. wagtail/contrib/search_promotions/locale/nb/LC_MESSAGES/django.mo +0 -0
  447. wagtail/contrib/search_promotions/locale/nb/LC_MESSAGES/django.po +1 -7
  448. wagtail/contrib/search_promotions/locale/nl/LC_MESSAGES/django.mo +0 -0
  449. wagtail/contrib/search_promotions/locale/nl/LC_MESSAGES/django.po +4 -4
  450. wagtail/contrib/search_promotions/locale/pl/LC_MESSAGES/django.mo +0 -0
  451. wagtail/contrib/search_promotions/locale/pl/LC_MESSAGES/django.po +1 -7
  452. wagtail/contrib/search_promotions/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  453. wagtail/contrib/search_promotions/locale/pt_BR/LC_MESSAGES/django.po +1 -7
  454. wagtail/contrib/search_promotions/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  455. wagtail/contrib/search_promotions/locale/pt_PT/LC_MESSAGES/django.po +1 -7
  456. wagtail/contrib/search_promotions/locale/ro/LC_MESSAGES/django.mo +0 -0
  457. wagtail/contrib/search_promotions/locale/ro/LC_MESSAGES/django.po +1 -7
  458. wagtail/contrib/search_promotions/locale/ru/LC_MESSAGES/django.mo +0 -0
  459. wagtail/contrib/search_promotions/locale/ru/LC_MESSAGES/django.po +1 -7
  460. wagtail/contrib/search_promotions/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  461. wagtail/contrib/search_promotions/locale/sk_SK/LC_MESSAGES/django.po +1 -7
  462. wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.mo +0 -0
  463. wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.po +1 -7
  464. wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.mo +0 -0
  465. wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.po +1 -7
  466. wagtail/contrib/search_promotions/locale/tet/LC_MESSAGES/django.mo +0 -0
  467. wagtail/contrib/search_promotions/locale/tet/LC_MESSAGES/django.po +1 -7
  468. wagtail/contrib/search_promotions/locale/th/LC_MESSAGES/django.mo +0 -0
  469. wagtail/contrib/search_promotions/locale/th/LC_MESSAGES/django.po +1 -7
  470. wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.mo +0 -0
  471. wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.po +44 -10
  472. wagtail/contrib/search_promotions/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
  473. wagtail/contrib/search_promotions/locale/tr_TR/LC_MESSAGES/django.po +1 -7
  474. wagtail/contrib/search_promotions/locale/ug/LC_MESSAGES/django.mo +0 -0
  475. wagtail/contrib/search_promotions/locale/ug/LC_MESSAGES/django.po +1 -7
  476. wagtail/contrib/search_promotions/locale/uk/LC_MESSAGES/django.mo +0 -0
  477. wagtail/contrib/search_promotions/locale/uk/LC_MESSAGES/django.po +1 -7
  478. wagtail/contrib/search_promotions/locale/vi/LC_MESSAGES/django.po +1 -1
  479. wagtail/contrib/search_promotions/locale/zh/LC_MESSAGES/django.po +1 -1
  480. wagtail/contrib/search_promotions/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  481. wagtail/contrib/search_promotions/locale/zh_Hans/LC_MESSAGES/django.po +1 -7
  482. wagtail/contrib/search_promotions/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
  483. wagtail/contrib/search_promotions/locale/zh_Hant/LC_MESSAGES/django.po +1 -7
  484. wagtail/contrib/search_promotions/static/wagtailsearchpromotions/js/query-chooser-modal.js +1 -1
  485. wagtail/contrib/search_promotions/views/settings.py +2 -2
  486. wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.mo +0 -0
  487. wagtail/contrib/settings/locale/cs/LC_MESSAGES/django.po +6 -1
  488. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +1 -1
  489. wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.mo +0 -0
  490. wagtail/contrib/settings/locale/nl/LC_MESSAGES/django.po +6 -2
  491. wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.mo +0 -0
  492. wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.po +6 -1
  493. wagtail/contrib/settings/tests/site_specific/test_admin.py +48 -6
  494. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
  495. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
  496. wagtail/contrib/styleguide/templates/wagtailstyleguide/base.html +5 -5
  497. wagtail/contrib/table_block/blocks.py +1 -0
  498. wagtail/contrib/table_block/locale/ar/LC_MESSAGES/django.po +1 -1
  499. wagtail/contrib/table_block/locale/be/LC_MESSAGES/django.po +1 -1
  500. wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.mo +0 -0
  501. wagtail/contrib/table_block/locale/ca/LC_MESSAGES/django.po +6 -3
  502. wagtail/contrib/table_block/locale/cs/LC_MESSAGES/django.po +1 -1
  503. wagtail/contrib/table_block/locale/cy/LC_MESSAGES/django.po +1 -1
  504. wagtail/contrib/table_block/locale/de/LC_MESSAGES/django.po +1 -1
  505. wagtail/contrib/table_block/locale/dv/LC_MESSAGES/django.po +1 -1
  506. wagtail/contrib/table_block/locale/el/LC_MESSAGES/django.po +1 -1
  507. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +5 -1
  508. wagtail/contrib/table_block/locale/en_IN/LC_MESSAGES/django.po +1 -1
  509. wagtail/contrib/table_block/locale/es/LC_MESSAGES/django.po +1 -1
  510. wagtail/contrib/table_block/locale/et/LC_MESSAGES/django.po +1 -1
  511. wagtail/contrib/table_block/locale/fa/LC_MESSAGES/django.po +1 -1
  512. wagtail/contrib/table_block/locale/fi/LC_MESSAGES/django.po +1 -1
  513. wagtail/contrib/table_block/locale/fr/LC_MESSAGES/django.mo +0 -0
  514. wagtail/contrib/table_block/locale/fr/LC_MESSAGES/django.po +6 -3
  515. wagtail/contrib/table_block/locale/gl/LC_MESSAGES/django.mo +0 -0
  516. wagtail/contrib/table_block/locale/gl/LC_MESSAGES/django.po +6 -3
  517. wagtail/contrib/table_block/locale/hr_HR/LC_MESSAGES/django.po +1 -1
  518. wagtail/contrib/table_block/locale/ht/LC_MESSAGES/django.po +1 -1
  519. wagtail/contrib/table_block/locale/hu/LC_MESSAGES/django.po +1 -1
  520. wagtail/contrib/table_block/locale/id_ID/LC_MESSAGES/django.po +1 -1
  521. wagtail/contrib/table_block/locale/is_IS/LC_MESSAGES/django.po +1 -1
  522. wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.po +1 -1
  523. wagtail/contrib/table_block/locale/ja/LC_MESSAGES/django.po +1 -1
  524. wagtail/contrib/table_block/locale/ko/LC_MESSAGES/django.po +1 -1
  525. wagtail/contrib/table_block/locale/lt/LC_MESSAGES/django.po +1 -1
  526. wagtail/contrib/table_block/locale/lv/LC_MESSAGES/django.po +1 -1
  527. wagtail/contrib/table_block/locale/mi/LC_MESSAGES/django.po +1 -1
  528. wagtail/contrib/table_block/locale/mn/LC_MESSAGES/django.po +1 -1
  529. wagtail/contrib/table_block/locale/my/LC_MESSAGES/django.po +1 -1
  530. wagtail/contrib/table_block/locale/nb/LC_MESSAGES/django.po +1 -1
  531. wagtail/contrib/table_block/locale/nl/LC_MESSAGES/django.mo +0 -0
  532. wagtail/contrib/table_block/locale/nl/LC_MESSAGES/django.po +6 -3
  533. wagtail/contrib/table_block/locale/pl/LC_MESSAGES/django.po +1 -1
  534. wagtail/contrib/table_block/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  535. wagtail/contrib/table_block/locale/pt_PT/LC_MESSAGES/django.po +1 -1
  536. wagtail/contrib/table_block/locale/ro/LC_MESSAGES/django.po +1 -1
  537. wagtail/contrib/table_block/locale/ru/LC_MESSAGES/django.po +1 -1
  538. wagtail/contrib/table_block/locale/sk_SK/LC_MESSAGES/django.po +1 -1
  539. wagtail/contrib/table_block/locale/sl/LC_MESSAGES/django.po +1 -1
  540. wagtail/contrib/table_block/locale/sv/LC_MESSAGES/django.po +1 -1
  541. wagtail/contrib/table_block/locale/tet/LC_MESSAGES/django.po +1 -1
  542. wagtail/contrib/table_block/locale/th/LC_MESSAGES/django.po +1 -1
  543. wagtail/contrib/table_block/locale/tr/LC_MESSAGES/django.po +1 -1
  544. wagtail/contrib/table_block/locale/tr_TR/LC_MESSAGES/django.po +1 -1
  545. wagtail/contrib/table_block/locale/ug/LC_MESSAGES/django.po +1 -1
  546. wagtail/contrib/table_block/locale/uk/LC_MESSAGES/django.po +1 -1
  547. wagtail/contrib/table_block/locale/vi/LC_MESSAGES/django.po +1 -1
  548. wagtail/contrib/table_block/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
  549. wagtail/contrib/table_block/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
  550. wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
  551. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
  552. wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
  553. wagtail/coreutils.py +5 -5
  554. wagtail/documents/forms.py +18 -1
  555. wagtail/documents/locale/af/LC_MESSAGES/django.po +1 -1
  556. wagtail/documents/locale/ar/LC_MESSAGES/django.mo +0 -0
  557. wagtail/documents/locale/ar/LC_MESSAGES/django.po +1 -5
  558. wagtail/documents/locale/az_AZ/LC_MESSAGES/django.po +1 -1
  559. wagtail/documents/locale/be/LC_MESSAGES/django.mo +0 -0
  560. wagtail/documents/locale/be/LC_MESSAGES/django.po +1 -5
  561. wagtail/documents/locale/bg/LC_MESSAGES/django.po +1 -1
  562. wagtail/documents/locale/bn/LC_MESSAGES/django.po +1 -1
  563. wagtail/documents/locale/ca/LC_MESSAGES/django.mo +0 -0
  564. wagtail/documents/locale/ca/LC_MESSAGES/django.po +5 -5
  565. wagtail/documents/locale/cs/LC_MESSAGES/django.mo +0 -0
  566. wagtail/documents/locale/cs/LC_MESSAGES/django.po +1 -7
  567. wagtail/documents/locale/cy/LC_MESSAGES/django.po +1 -1
  568. wagtail/documents/locale/da/LC_MESSAGES/django.po +1 -1
  569. wagtail/documents/locale/de/LC_MESSAGES/django.mo +0 -0
  570. wagtail/documents/locale/de/LC_MESSAGES/django.po +1 -7
  571. wagtail/documents/locale/dv/LC_MESSAGES/django.po +1 -1
  572. wagtail/documents/locale/el/LC_MESSAGES/django.mo +0 -0
  573. wagtail/documents/locale/el/LC_MESSAGES/django.po +1 -7
  574. wagtail/documents/locale/en/LC_MESSAGES/django.po +10 -10
  575. wagtail/documents/locale/es/LC_MESSAGES/django.mo +0 -0
  576. wagtail/documents/locale/es/LC_MESSAGES/django.po +1 -7
  577. wagtail/documents/locale/es_419/LC_MESSAGES/django.po +1 -1
  578. wagtail/documents/locale/et/LC_MESSAGES/django.mo +0 -0
  579. wagtail/documents/locale/et/LC_MESSAGES/django.po +1 -5
  580. wagtail/documents/locale/eu/LC_MESSAGES/django.po +1 -1
  581. wagtail/documents/locale/fa/LC_MESSAGES/django.mo +0 -0
  582. wagtail/documents/locale/fa/LC_MESSAGES/django.po +1 -5
  583. wagtail/documents/locale/fi/LC_MESSAGES/django.mo +0 -0
  584. wagtail/documents/locale/fi/LC_MESSAGES/django.po +1 -5
  585. wagtail/documents/locale/fr/LC_MESSAGES/django.mo +0 -0
  586. wagtail/documents/locale/fr/LC_MESSAGES/django.po +5 -5
  587. wagtail/documents/locale/gl/LC_MESSAGES/django.mo +0 -0
  588. wagtail/documents/locale/gl/LC_MESSAGES/django.po +5 -5
  589. wagtail/documents/locale/he_IL/LC_MESSAGES/django.mo +0 -0
  590. wagtail/documents/locale/he_IL/LC_MESSAGES/django.po +1 -5
  591. wagtail/documents/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  592. wagtail/documents/locale/hr_HR/LC_MESSAGES/django.po +1 -6
  593. wagtail/documents/locale/ht/LC_MESSAGES/django.po +1 -1
  594. wagtail/documents/locale/hu/LC_MESSAGES/django.mo +0 -0
  595. wagtail/documents/locale/hu/LC_MESSAGES/django.po +1 -7
  596. wagtail/documents/locale/id_ID/LC_MESSAGES/django.mo +0 -0
  597. wagtail/documents/locale/id_ID/LC_MESSAGES/django.po +1 -6
  598. wagtail/documents/locale/is_IS/LC_MESSAGES/django.mo +0 -0
  599. wagtail/documents/locale/is_IS/LC_MESSAGES/django.po +1 -5
  600. wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
  601. wagtail/documents/locale/it/LC_MESSAGES/django.po +1 -5
  602. wagtail/documents/locale/ja/LC_MESSAGES/django.mo +0 -0
  603. wagtail/documents/locale/ja/LC_MESSAGES/django.po +1 -7
  604. wagtail/documents/locale/ka/LC_MESSAGES/django.po +1 -1
  605. wagtail/documents/locale/ko/LC_MESSAGES/django.mo +0 -0
  606. wagtail/documents/locale/ko/LC_MESSAGES/django.po +1 -6
  607. wagtail/documents/locale/lt/LC_MESSAGES/django.mo +0 -0
  608. wagtail/documents/locale/lt/LC_MESSAGES/django.po +1 -5
  609. wagtail/documents/locale/lv/LC_MESSAGES/django.po +1 -1
  610. wagtail/documents/locale/mi/LC_MESSAGES/django.mo +0 -0
  611. wagtail/documents/locale/mi/LC_MESSAGES/django.po +1 -7
  612. wagtail/documents/locale/mn/LC_MESSAGES/django.mo +0 -0
  613. wagtail/documents/locale/mn/LC_MESSAGES/django.po +1 -5
  614. wagtail/documents/locale/my/LC_MESSAGES/django.po +1 -1
  615. wagtail/documents/locale/nb/LC_MESSAGES/django.mo +0 -0
  616. wagtail/documents/locale/nb/LC_MESSAGES/django.po +1 -5
  617. wagtail/documents/locale/nl/LC_MESSAGES/django.mo +0 -0
  618. wagtail/documents/locale/nl/LC_MESSAGES/django.po +15 -6
  619. wagtail/documents/locale/pl/LC_MESSAGES/django.mo +0 -0
  620. wagtail/documents/locale/pl/LC_MESSAGES/django.po +1 -6
  621. wagtail/documents/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  622. wagtail/documents/locale/pt_BR/LC_MESSAGES/django.po +1 -7
  623. wagtail/documents/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  624. wagtail/documents/locale/pt_PT/LC_MESSAGES/django.po +1 -6
  625. wagtail/documents/locale/ro/LC_MESSAGES/django.mo +0 -0
  626. wagtail/documents/locale/ro/LC_MESSAGES/django.po +1 -5
  627. wagtail/documents/locale/ru/LC_MESSAGES/django.mo +0 -0
  628. wagtail/documents/locale/ru/LC_MESSAGES/django.po +10 -7
  629. wagtail/documents/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  630. wagtail/documents/locale/sk_SK/LC_MESSAGES/django.po +1 -5
  631. wagtail/documents/locale/sl/LC_MESSAGES/django.mo +0 -0
  632. wagtail/documents/locale/sl/LC_MESSAGES/django.po +1 -7
  633. wagtail/documents/locale/sv/LC_MESSAGES/django.mo +0 -0
  634. wagtail/documents/locale/sv/LC_MESSAGES/django.po +1 -6
  635. wagtail/documents/locale/tet/LC_MESSAGES/django.po +1 -1
  636. wagtail/documents/locale/th/LC_MESSAGES/django.mo +0 -0
  637. wagtail/documents/locale/th/LC_MESSAGES/django.po +1 -5
  638. wagtail/documents/locale/tr/LC_MESSAGES/django.mo +0 -0
  639. wagtail/documents/locale/tr/LC_MESSAGES/django.po +13 -5
  640. wagtail/documents/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
  641. wagtail/documents/locale/tr_TR/LC_MESSAGES/django.po +1 -5
  642. wagtail/documents/locale/ug/LC_MESSAGES/django.mo +0 -0
  643. wagtail/documents/locale/ug/LC_MESSAGES/django.po +1 -5
  644. wagtail/documents/locale/uk/LC_MESSAGES/django.mo +0 -0
  645. wagtail/documents/locale/uk/LC_MESSAGES/django.po +1 -5
  646. wagtail/documents/locale/vi/LC_MESSAGES/django.po +1 -1
  647. wagtail/documents/locale/zh/LC_MESSAGES/django.po +1 -1
  648. wagtail/documents/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  649. wagtail/documents/locale/zh_Hans/LC_MESSAGES/django.po +1 -5
  650. wagtail/documents/locale/zh_Hant/LC_MESSAGES/django.mo +0 -0
  651. wagtail/documents/locale/zh_Hant/LC_MESSAGES/django.po +1 -5
  652. wagtail/documents/models.py +1 -1
  653. wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
  654. wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
  655. wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
  656. wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
  657. wagtail/documents/templates/wagtaildocs/documents/add.html +0 -34
  658. wagtail/documents/tests/test_admin_views.py +132 -26
  659. wagtail/documents/tests/test_collection_privacy.py +18 -4
  660. wagtail/documents/tests/test_form_overrides.py +1 -1
  661. wagtail/documents/tests/test_search.py +21 -8
  662. wagtail/documents/views/documents.py +1 -1
  663. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  664. wagtail/embeds/static/wagtailembeds/js/embed-chooser-modal.js +1 -1
  665. wagtail/images/forms.py +16 -1
  666. wagtail/images/locale/ar/LC_MESSAGES/django.mo +0 -0
  667. wagtail/images/locale/ar/LC_MESSAGES/django.po +7 -10
  668. wagtail/images/locale/az_AZ/LC_MESSAGES/django.po +1 -1
  669. wagtail/images/locale/be/LC_MESSAGES/django.po +7 -7
  670. wagtail/images/locale/bg/LC_MESSAGES/django.po +4 -4
  671. wagtail/images/locale/bn/LC_MESSAGES/django.po +1 -1
  672. wagtail/images/locale/ca/LC_MESSAGES/django.mo +0 -0
  673. wagtail/images/locale/ca/LC_MESSAGES/django.po +15 -9
  674. wagtail/images/locale/cs/LC_MESSAGES/django.mo +0 -0
  675. wagtail/images/locale/cs/LC_MESSAGES/django.po +19 -8
  676. wagtail/images/locale/cy/LC_MESSAGES/django.po +4 -4
  677. wagtail/images/locale/da/LC_MESSAGES/django.po +1 -1
  678. wagtail/images/locale/de/LC_MESSAGES/django.po +7 -7
  679. wagtail/images/locale/dv/LC_MESSAGES/django.po +7 -7
  680. wagtail/images/locale/el/LC_MESSAGES/django.po +7 -7
  681. wagtail/images/locale/en/LC_MESSAGES/django.po +57 -46
  682. wagtail/images/locale/es/LC_MESSAGES/django.po +7 -7
  683. wagtail/images/locale/es_419/LC_MESSAGES/django.po +1 -1
  684. wagtail/images/locale/et/LC_MESSAGES/django.po +7 -7
  685. wagtail/images/locale/eu/LC_MESSAGES/django.po +1 -1
  686. wagtail/images/locale/fa/LC_MESSAGES/django.po +4 -4
  687. wagtail/images/locale/fi/LC_MESSAGES/django.mo +0 -0
  688. wagtail/images/locale/fi/LC_MESSAGES/django.po +18 -9
  689. wagtail/images/locale/fr/LC_MESSAGES/django.mo +0 -0
  690. wagtail/images/locale/fr/LC_MESSAGES/django.po +15 -9
  691. wagtail/images/locale/gl/LC_MESSAGES/django.mo +0 -0
  692. wagtail/images/locale/gl/LC_MESSAGES/django.po +15 -9
  693. wagtail/images/locale/he_IL/LC_MESSAGES/django.po +4 -4
  694. wagtail/images/locale/hr_HR/LC_MESSAGES/django.po +7 -7
  695. wagtail/images/locale/ht/LC_MESSAGES/django.po +1 -1
  696. wagtail/images/locale/hu/LC_MESSAGES/django.mo +0 -0
  697. wagtail/images/locale/hu/LC_MESSAGES/django.po +7 -10
  698. wagtail/images/locale/id_ID/LC_MESSAGES/django.po +4 -4
  699. wagtail/images/locale/is_IS/LC_MESSAGES/django.po +7 -7
  700. wagtail/images/locale/it/LC_MESSAGES/django.po +7 -7
  701. wagtail/images/locale/ja/LC_MESSAGES/django.po +7 -7
  702. wagtail/images/locale/ka/LC_MESSAGES/django.po +4 -4
  703. wagtail/images/locale/ko/LC_MESSAGES/django.po +7 -7
  704. wagtail/images/locale/lt/LC_MESSAGES/django.po +7 -7
  705. wagtail/images/locale/lv/LC_MESSAGES/django.po +4 -4
  706. wagtail/images/locale/mi/LC_MESSAGES/django.po +7 -7
  707. wagtail/images/locale/mn/LC_MESSAGES/django.po +4 -4
  708. wagtail/images/locale/my/LC_MESSAGES/django.po +1 -1
  709. wagtail/images/locale/nb/LC_MESSAGES/django.po +7 -7
  710. wagtail/images/locale/nl/LC_MESSAGES/django.mo +0 -0
  711. wagtail/images/locale/nl/LC_MESSAGES/django.po +50 -21
  712. wagtail/images/locale/pl/LC_MESSAGES/django.po +7 -7
  713. wagtail/images/locale/pt_BR/LC_MESSAGES/django.po +7 -7
  714. wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +7 -7
  715. wagtail/images/locale/ro/LC_MESSAGES/django.po +7 -7
  716. wagtail/images/locale/ru/LC_MESSAGES/django.mo +0 -0
  717. wagtail/images/locale/ru/LC_MESSAGES/django.po +24 -8
  718. wagtail/images/locale/sk_SK/LC_MESSAGES/django.po +4 -4
  719. wagtail/images/locale/sl/LC_MESSAGES/django.po +7 -7
  720. wagtail/images/locale/sv/LC_MESSAGES/django.po +7 -7
  721. wagtail/images/locale/tet/LC_MESSAGES/django.po +4 -4
  722. wagtail/images/locale/th/LC_MESSAGES/django.po +4 -4
  723. wagtail/images/locale/tr/LC_MESSAGES/django.mo +0 -0
  724. wagtail/images/locale/tr/LC_MESSAGES/django.po +85 -7
  725. wagtail/images/locale/tr_TR/LC_MESSAGES/django.po +4 -4
  726. wagtail/images/locale/ug/LC_MESSAGES/django.po +7 -7
  727. wagtail/images/locale/uk/LC_MESSAGES/django.po +7 -7
  728. wagtail/images/locale/vi/LC_MESSAGES/django.po +4 -4
  729. wagtail/images/locale/zh/LC_MESSAGES/django.po +4 -4
  730. wagtail/images/locale/zh_Hans/LC_MESSAGES/django.po +7 -7
  731. wagtail/images/locale/zh_Hant/LC_MESSAGES/django.po +7 -7
  732. wagtail/images/models.py +1 -1
  733. wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
  734. wagtail/images/static/wagtailimages/js/focal-point-chooser.js +1 -1
  735. wagtail/images/static/wagtailimages/js/image-block.js +1 -1
  736. wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
  737. wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
  738. wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
  739. wagtail/images/static/wagtailimages/js/image-url-generator.js +1 -1
  740. wagtail/images/static/wagtailimages/js/vendor/jquery.Jcrop.min.js +1 -1
  741. wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-image.js +1 -1
  742. wagtail/images/static/wagtailimages/js/vendor/jquery.fileupload-validate.js +1 -1
  743. wagtail/images/static/wagtailimages/js/vendor/load-image.min.js +1 -1
  744. wagtail/images/templates/wagtailimages/chooser/chooser.html +22 -13
  745. wagtail/images/templates/wagtailimages/chooser/image_preview_column_cell.html +10 -0
  746. wagtail/images/templates/wagtailimages/chooser/results.html +24 -20
  747. wagtail/images/templates/wagtailimages/chooser/title_column_cell.html +15 -0
  748. wagtail/images/templates/wagtailimages/images/add.html +0 -34
  749. wagtail/images/templates/wagtailimages/images/index.html +3 -3
  750. wagtail/images/templates/wagtailimages/images/index_results.html +1 -1
  751. wagtail/images/templates/wagtailimages/images/layout_toggle_button.html +8 -7
  752. wagtail/images/templatetags/wagtailimages_tags.py +2 -2
  753. wagtail/images/tests/test_admin_views.py +87 -0
  754. wagtail/images/tests/test_form_overrides.py +1 -1
  755. wagtail/images/tests/test_models.py +48 -9
  756. wagtail/images/views/chooser.py +66 -2
  757. wagtail/locale/af/LC_MESSAGES/django.po +1 -1
  758. wagtail/locale/ar/LC_MESSAGES/django.mo +0 -0
  759. wagtail/locale/ar/LC_MESSAGES/django.po +1 -9
  760. wagtail/locale/az_AZ/LC_MESSAGES/django.po +1 -1
  761. wagtail/locale/be/LC_MESSAGES/django.po +1 -1
  762. wagtail/locale/bg/LC_MESSAGES/django.po +1 -1
  763. wagtail/locale/bn/LC_MESSAGES/django.po +1 -1
  764. wagtail/locale/ca/LC_MESSAGES/django.mo +0 -0
  765. wagtail/locale/ca/LC_MESSAGES/django.po +4 -4
  766. wagtail/locale/cs/LC_MESSAGES/django.po +1 -1
  767. wagtail/locale/cy/LC_MESSAGES/django.po +1 -1
  768. wagtail/locale/da/LC_MESSAGES/django.po +1 -1
  769. wagtail/locale/de/LC_MESSAGES/django.mo +0 -0
  770. wagtail/locale/de/LC_MESSAGES/django.po +1 -9
  771. wagtail/locale/dv/LC_MESSAGES/django.mo +0 -0
  772. wagtail/locale/dv/LC_MESSAGES/django.po +1 -8
  773. wagtail/locale/el/LC_MESSAGES/django.po +1 -1
  774. wagtail/locale/en/LC_MESSAGES/django.po +55 -55
  775. wagtail/locale/es/LC_MESSAGES/django.po +1 -1
  776. wagtail/locale/es_419/LC_MESSAGES/django.po +1 -1
  777. wagtail/locale/et/LC_MESSAGES/django.po +1 -1
  778. wagtail/locale/eu/LC_MESSAGES/django.po +1 -1
  779. wagtail/locale/fa/LC_MESSAGES/django.po +1 -1
  780. wagtail/locale/fi/LC_MESSAGES/django.po +1 -1
  781. wagtail/locale/fr/LC_MESSAGES/django.mo +0 -0
  782. wagtail/locale/fr/LC_MESSAGES/django.po +4 -4
  783. wagtail/locale/gl/LC_MESSAGES/django.mo +0 -0
  784. wagtail/locale/gl/LC_MESSAGES/django.po +3 -3
  785. wagtail/locale/he_IL/LC_MESSAGES/django.po +1 -1
  786. wagtail/locale/hr_HR/LC_MESSAGES/django.po +1 -1
  787. wagtail/locale/hu/LC_MESSAGES/django.mo +0 -0
  788. wagtail/locale/hu/LC_MESSAGES/django.po +1 -9
  789. wagtail/locale/id_ID/LC_MESSAGES/django.po +1 -1
  790. wagtail/locale/is_IS/LC_MESSAGES/django.mo +0 -0
  791. wagtail/locale/is_IS/LC_MESSAGES/django.po +4 -12
  792. wagtail/locale/it/LC_MESSAGES/django.po +1 -1
  793. wagtail/locale/ja/LC_MESSAGES/django.po +1 -1
  794. wagtail/locale/ka/LC_MESSAGES/django.po +1 -1
  795. wagtail/locale/ko/LC_MESSAGES/django.po +1 -1
  796. wagtail/locale/lt/LC_MESSAGES/django.po +1 -1
  797. wagtail/locale/lv/LC_MESSAGES/django.po +1 -1
  798. wagtail/locale/mi/LC_MESSAGES/django.po +1 -1
  799. wagtail/locale/mn/LC_MESSAGES/django.po +1 -1
  800. wagtail/locale/my/LC_MESSAGES/django.po +1 -1
  801. wagtail/locale/nb/LC_MESSAGES/django.po +1 -1
  802. wagtail/locale/nl/LC_MESSAGES/django.mo +0 -0
  803. wagtail/locale/nl/LC_MESSAGES/django.po +15 -6
  804. wagtail/locale/pl/LC_MESSAGES/django.mo +0 -0
  805. wagtail/locale/pl/LC_MESSAGES/django.po +1 -9
  806. wagtail/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  807. wagtail/locale/pt_PT/LC_MESSAGES/django.po +1 -1
  808. wagtail/locale/ro/LC_MESSAGES/django.mo +0 -0
  809. wagtail/locale/ro/LC_MESSAGES/django.po +1 -9
  810. wagtail/locale/ru/LC_MESSAGES/django.mo +0 -0
  811. wagtail/locale/ru/LC_MESSAGES/django.po +12 -10
  812. wagtail/locale/sk_SK/LC_MESSAGES/django.po +1 -1
  813. wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
  814. wagtail/locale/sl/LC_MESSAGES/django.po +1 -9
  815. wagtail/locale/sv/LC_MESSAGES/django.mo +0 -0
  816. wagtail/locale/sv/LC_MESSAGES/django.po +1 -9
  817. wagtail/locale/tet/LC_MESSAGES/django.po +1 -1
  818. wagtail/locale/th/LC_MESSAGES/django.po +1 -1
  819. wagtail/locale/tr/LC_MESSAGES/django.mo +0 -0
  820. wagtail/locale/tr/LC_MESSAGES/django.po +4 -8
  821. wagtail/locale/tr_TR/LC_MESSAGES/django.po +1 -1
  822. wagtail/locale/ug/LC_MESSAGES/django.mo +0 -0
  823. wagtail/locale/ug/LC_MESSAGES/django.po +1 -8
  824. wagtail/locale/uk/LC_MESSAGES/django.po +1 -1
  825. wagtail/locale/vi/LC_MESSAGES/django.po +1 -1
  826. wagtail/locale/zh/LC_MESSAGES/django.po +1 -1
  827. wagtail/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
  828. wagtail/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
  829. wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
  830. wagtail/locales/locale/nl/LC_MESSAGES/django.mo +0 -0
  831. wagtail/locales/locale/nl/LC_MESSAGES/django.po +12 -1
  832. wagtail/locales/locale/ru/LC_MESSAGES/django.mo +0 -0
  833. wagtail/locales/locale/ru/LC_MESSAGES/django.po +10 -1
  834. wagtail/locales/views.py +2 -2
  835. wagtail/models/orderable.py +10 -0
  836. wagtail/models/pages.py +9 -11
  837. wagtail/models/sites.py +1 -1
  838. wagtail/models/workflows.py +8 -5
  839. wagtail/project_template/home/tests.py +6 -7
  840. wagtail/project_template/project_name/settings/base.py +9 -9
  841. wagtail/project_template/requirements.txt +1 -1
  842. wagtail/query.py +7 -2
  843. wagtail/rich_text/rewriters.py +1 -1
  844. wagtail/search/apps.py +4 -49
  845. wagtail/search/backends/__init__.py +1 -113
  846. wagtail/search/backends/base.py +1 -547
  847. wagtail/search/backends/database/__init__.py +1 -50
  848. wagtail/search/backends/database/fallback.py +1 -253
  849. wagtail/search/backends/database/mysql/mysql.py +1 -700
  850. wagtail/search/backends/database/mysql/query.py +1 -258
  851. wagtail/search/backends/database/postgres/postgres.py +1 -749
  852. wagtail/search/backends/database/postgres/query.py +1 -83
  853. wagtail/search/backends/database/postgres/weights.py +1 -63
  854. wagtail/search/backends/database/sqlite/query.py +1 -294
  855. wagtail/search/backends/database/sqlite/sqlite.py +1 -719
  856. wagtail/search/backends/database/sqlite/utils.py +1 -35
  857. wagtail/search/backends/deprecation.py +45 -0
  858. wagtail/search/backends/elasticsearch7.py +18 -1260
  859. wagtail/search/backends/elasticsearch8.py +21 -96
  860. wagtail/search/backends/elasticsearch9.py +35 -0
  861. wagtail/search/backends/opensearch2.py +35 -0
  862. wagtail/search/backends/opensearch3.py +35 -0
  863. wagtail/search/index.py +1 -358
  864. wagtail/search/locale/ar/LC_MESSAGES/django.mo +0 -0
  865. wagtail/search/locale/ar/LC_MESSAGES/django.po +1 -7
  866. wagtail/search/locale/be/LC_MESSAGES/django.mo +0 -0
  867. wagtail/search/locale/be/LC_MESSAGES/django.po +1 -7
  868. wagtail/search/locale/ca/LC_MESSAGES/django.mo +0 -0
  869. wagtail/search/locale/ca/LC_MESSAGES/django.po +1 -7
  870. wagtail/search/locale/cs/LC_MESSAGES/django.po +1 -1
  871. wagtail/search/locale/cy/LC_MESSAGES/django.mo +0 -0
  872. wagtail/search/locale/cy/LC_MESSAGES/django.po +1 -7
  873. wagtail/search/locale/de/LC_MESSAGES/django.mo +0 -0
  874. wagtail/search/locale/de/LC_MESSAGES/django.po +1 -7
  875. wagtail/search/locale/dv/LC_MESSAGES/django.mo +0 -0
  876. wagtail/search/locale/dv/LC_MESSAGES/django.po +1 -7
  877. wagtail/search/locale/en/LC_MESSAGES/django.po +2 -10
  878. wagtail/search/locale/es/LC_MESSAGES/django.mo +0 -0
  879. wagtail/search/locale/es/LC_MESSAGES/django.po +1 -7
  880. wagtail/search/locale/et/LC_MESSAGES/django.po +1 -1
  881. wagtail/search/locale/fa/LC_MESSAGES/django.po +1 -1
  882. wagtail/search/locale/fi/LC_MESSAGES/django.mo +0 -0
  883. wagtail/search/locale/fi/LC_MESSAGES/django.po +1 -7
  884. wagtail/search/locale/fr/LC_MESSAGES/django.mo +0 -0
  885. wagtail/search/locale/fr/LC_MESSAGES/django.po +1 -7
  886. wagtail/search/locale/gl/LC_MESSAGES/django.mo +0 -0
  887. wagtail/search/locale/gl/LC_MESSAGES/django.po +1 -7
  888. wagtail/search/locale/hr_HR/LC_MESSAGES/django.mo +0 -0
  889. wagtail/search/locale/hr_HR/LC_MESSAGES/django.po +1 -7
  890. wagtail/search/locale/ht/LC_MESSAGES/django.po +1 -1
  891. wagtail/search/locale/hu/LC_MESSAGES/django.mo +0 -0
  892. wagtail/search/locale/hu/LC_MESSAGES/django.po +1 -7
  893. wagtail/search/locale/id_ID/LC_MESSAGES/django.po +1 -1
  894. wagtail/search/locale/is_IS/LC_MESSAGES/django.mo +0 -0
  895. wagtail/search/locale/is_IS/LC_MESSAGES/django.po +1 -7
  896. wagtail/search/locale/it/LC_MESSAGES/django.mo +0 -0
  897. wagtail/search/locale/it/LC_MESSAGES/django.po +1 -7
  898. wagtail/search/locale/ja/LC_MESSAGES/django.po +1 -1
  899. wagtail/search/locale/ko/LC_MESSAGES/django.mo +0 -0
  900. wagtail/search/locale/ko/LC_MESSAGES/django.po +1 -7
  901. wagtail/search/locale/lt/LC_MESSAGES/django.po +1 -1
  902. wagtail/search/locale/mi/LC_MESSAGES/django.po +1 -1
  903. wagtail/search/locale/mn/LC_MESSAGES/django.po +1 -1
  904. wagtail/search/locale/my/LC_MESSAGES/django.po +1 -1
  905. wagtail/search/locale/nb/LC_MESSAGES/django.mo +0 -0
  906. wagtail/search/locale/nb/LC_MESSAGES/django.po +1 -7
  907. wagtail/search/locale/nl/LC_MESSAGES/django.mo +0 -0
  908. wagtail/search/locale/nl/LC_MESSAGES/django.po +1 -7
  909. wagtail/search/locale/pl/LC_MESSAGES/django.mo +0 -0
  910. wagtail/search/locale/pl/LC_MESSAGES/django.po +1 -7
  911. wagtail/search/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  912. wagtail/search/locale/pt_BR/LC_MESSAGES/django.po +1 -7
  913. wagtail/search/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  914. wagtail/search/locale/pt_PT/LC_MESSAGES/django.po +1 -7
  915. wagtail/search/locale/ro/LC_MESSAGES/django.mo +0 -0
  916. wagtail/search/locale/ro/LC_MESSAGES/django.po +1 -7
  917. wagtail/search/locale/ru/LC_MESSAGES/django.mo +0 -0
  918. wagtail/search/locale/ru/LC_MESSAGES/django.po +1 -7
  919. wagtail/search/locale/sl/LC_MESSAGES/django.mo +0 -0
  920. wagtail/search/locale/sl/LC_MESSAGES/django.po +1 -7
  921. wagtail/search/locale/sv/LC_MESSAGES/django.mo +0 -0
  922. wagtail/search/locale/sv/LC_MESSAGES/django.po +1 -7
  923. wagtail/search/locale/tet/LC_MESSAGES/django.po +1 -1
  924. wagtail/search/locale/th/LC_MESSAGES/django.po +1 -1
  925. wagtail/search/locale/tr/LC_MESSAGES/django.mo +0 -0
  926. wagtail/search/locale/tr/LC_MESSAGES/django.po +1 -7
  927. wagtail/search/locale/tr_TR/LC_MESSAGES/django.po +1 -1
  928. wagtail/search/locale/ug/LC_MESSAGES/django.mo +0 -0
  929. wagtail/search/locale/ug/LC_MESSAGES/django.po +1 -7
  930. wagtail/search/locale/uk/LC_MESSAGES/django.mo +0 -0
  931. wagtail/search/locale/uk/LC_MESSAGES/django.po +1 -7
  932. wagtail/search/locale/vi/LC_MESSAGES/django.po +1 -1
  933. wagtail/search/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  934. wagtail/search/locale/zh_Hans/LC_MESSAGES/django.po +1 -7
  935. wagtail/search/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
  936. wagtail/search/management/commands/update_index.py +1 -205
  937. wagtail/search/management/commands/wagtail_update_index.py +1 -4
  938. wagtail/search/models.py +29 -158
  939. wagtail/search/query.py +1 -114
  940. wagtail/search/queryset.py +1 -43
  941. wagtail/search/signal_handlers.py +1 -24
  942. wagtail/search/tasks.py +1 -10
  943. wagtail/search/tests/test_elasticsearch.py +22 -0
  944. wagtail/search/utils.py +1 -206
  945. wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
  946. wagtail/snippets/locale/af/LC_MESSAGES/django.po +1 -1
  947. wagtail/snippets/locale/ar/LC_MESSAGES/django.po +1 -1
  948. wagtail/snippets/locale/az_AZ/LC_MESSAGES/django.po +1 -1
  949. wagtail/snippets/locale/be/LC_MESSAGES/django.po +1 -1
  950. wagtail/snippets/locale/bg/LC_MESSAGES/django.po +1 -1
  951. wagtail/snippets/locale/bn/LC_MESSAGES/django.po +1 -1
  952. wagtail/snippets/locale/ca/LC_MESSAGES/django.po +1 -1
  953. wagtail/snippets/locale/cs/LC_MESSAGES/django.po +1 -1
  954. wagtail/snippets/locale/cy/LC_MESSAGES/django.po +1 -1
  955. wagtail/snippets/locale/da/LC_MESSAGES/django.po +1 -1
  956. wagtail/snippets/locale/de/LC_MESSAGES/django.po +1 -1
  957. wagtail/snippets/locale/dv/LC_MESSAGES/django.po +1 -1
  958. wagtail/snippets/locale/el/LC_MESSAGES/django.po +1 -1
  959. wagtail/snippets/locale/en/LC_MESSAGES/django.po +3 -3
  960. wagtail/snippets/locale/en_IN/LC_MESSAGES/django.po +1 -1
  961. wagtail/snippets/locale/es/LC_MESSAGES/django.po +1 -1
  962. wagtail/snippets/locale/es_419/LC_MESSAGES/django.po +1 -1
  963. wagtail/snippets/locale/es_VE/LC_MESSAGES/django.po +1 -1
  964. wagtail/snippets/locale/et/LC_MESSAGES/django.po +1 -1
  965. wagtail/snippets/locale/eu/LC_MESSAGES/django.po +1 -1
  966. wagtail/snippets/locale/fa/LC_MESSAGES/django.po +1 -1
  967. wagtail/snippets/locale/fi/LC_MESSAGES/django.po +1 -1
  968. wagtail/snippets/locale/fr/LC_MESSAGES/django.po +1 -1
  969. wagtail/snippets/locale/gl/LC_MESSAGES/django.po +1 -1
  970. wagtail/snippets/locale/he_IL/LC_MESSAGES/django.po +1 -1
  971. wagtail/snippets/locale/hi/LC_MESSAGES/django.po +1 -1
  972. wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.po +1 -1
  973. wagtail/snippets/locale/ht/LC_MESSAGES/django.po +1 -1
  974. wagtail/snippets/locale/hu/LC_MESSAGES/django.po +1 -1
  975. wagtail/snippets/locale/id_ID/LC_MESSAGES/django.po +1 -1
  976. wagtail/snippets/locale/is_IS/LC_MESSAGES/django.po +1 -1
  977. wagtail/snippets/locale/it/LC_MESSAGES/django.po +1 -1
  978. wagtail/snippets/locale/ja/LC_MESSAGES/django.po +1 -1
  979. wagtail/snippets/locale/ka/LC_MESSAGES/django.po +1 -1
  980. wagtail/snippets/locale/ko/LC_MESSAGES/django.po +1 -1
  981. wagtail/snippets/locale/lt/LC_MESSAGES/django.po +1 -1
  982. wagtail/snippets/locale/lv/LC_MESSAGES/django.po +1 -1
  983. wagtail/snippets/locale/mi/LC_MESSAGES/django.po +1 -1
  984. wagtail/snippets/locale/mn/LC_MESSAGES/django.po +1 -1
  985. wagtail/snippets/locale/my/LC_MESSAGES/django.po +1 -1
  986. wagtail/snippets/locale/nb/LC_MESSAGES/django.po +1 -1
  987. wagtail/snippets/locale/nl/LC_MESSAGES/django.po +1 -1
  988. wagtail/snippets/locale/pl/LC_MESSAGES/django.po +1 -1
  989. wagtail/snippets/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  990. wagtail/snippets/locale/pt_PT/LC_MESSAGES/django.po +1 -1
  991. wagtail/snippets/locale/ro/LC_MESSAGES/django.po +1 -1
  992. wagtail/snippets/locale/ru/LC_MESSAGES/django.mo +0 -0
  993. wagtail/snippets/locale/ru/LC_MESSAGES/django.po +9 -2
  994. wagtail/snippets/locale/sk_SK/LC_MESSAGES/django.po +1 -1
  995. wagtail/snippets/locale/sl/LC_MESSAGES/django.po +1 -1
  996. wagtail/snippets/locale/sr/LC_MESSAGES/django.po +1 -1
  997. wagtail/snippets/locale/sv/LC_MESSAGES/django.po +1 -1
  998. wagtail/snippets/locale/ta/LC_MESSAGES/django.po +1 -1
  999. wagtail/snippets/locale/tet/LC_MESSAGES/django.po +1 -1
  1000. wagtail/snippets/locale/th/LC_MESSAGES/django.po +1 -1
  1001. wagtail/snippets/locale/tr/LC_MESSAGES/django.mo +0 -0
  1002. wagtail/snippets/locale/tr/LC_MESSAGES/django.po +9 -2
  1003. wagtail/snippets/locale/tr_TR/LC_MESSAGES/django.po +1 -1
  1004. wagtail/snippets/locale/ug/LC_MESSAGES/django.po +1 -1
  1005. wagtail/snippets/locale/uk/LC_MESSAGES/django.po +1 -1
  1006. wagtail/snippets/locale/vi/LC_MESSAGES/django.po +1 -1
  1007. wagtail/snippets/locale/zh/LC_MESSAGES/django.po +1 -1
  1008. wagtail/snippets/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
  1009. wagtail/snippets/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
  1010. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  1011. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  1012. wagtail/snippets/tests/test_reordering.py +319 -0
  1013. wagtail/snippets/tests/test_snippets.py +77 -12
  1014. wagtail/snippets/views/snippets.py +16 -0
  1015. wagtail/test/numberformat.py +30 -0
  1016. wagtail/test/settings.py +35 -12
  1017. wagtail/test/testapp/fields.py +12 -0
  1018. wagtail/test/testapp/migrations/0056_commentablejsonpage.py +50 -0
  1019. wagtail/test/testapp/migrations/0057_featurecompletetoy_sort_order.py +23 -0
  1020. wagtail/test/testapp/migrations/0058_customlocktask.py +31 -0
  1021. wagtail/test/testapp/models.py +27 -0
  1022. wagtail/test/testapp/views.py +3 -1
  1023. wagtail/test/utils/page_tests.py +17 -17
  1024. wagtail/test/utils/template_tests.py +4 -6
  1025. wagtail/test/utils/wagtail_tests.py +1 -2
  1026. wagtail/tests/test_page_model.py +15 -0
  1027. wagtail/{search/tests → tests}/test_page_search.py +29 -2
  1028. wagtail/tests/test_search_fields.py +69 -0
  1029. wagtail/tests/test_tests.py +62 -6
  1030. wagtail/tests/test_workflow.py +25 -1
  1031. wagtail/users/locale/ar/LC_MESSAGES/django.po +1 -1
  1032. wagtail/users/locale/be/LC_MESSAGES/django.po +1 -1
  1033. wagtail/users/locale/bg/LC_MESSAGES/django.po +1 -1
  1034. wagtail/users/locale/bn/LC_MESSAGES/django.po +1 -1
  1035. wagtail/users/locale/ca/LC_MESSAGES/django.po +1 -1
  1036. wagtail/users/locale/cs/LC_MESSAGES/django.mo +0 -0
  1037. wagtail/users/locale/cs/LC_MESSAGES/django.po +4 -1
  1038. wagtail/users/locale/cy/LC_MESSAGES/django.po +1 -1
  1039. wagtail/users/locale/da/LC_MESSAGES/django.po +1 -1
  1040. wagtail/users/locale/de/LC_MESSAGES/django.po +1 -1
  1041. wagtail/users/locale/dv/LC_MESSAGES/django.po +1 -1
  1042. wagtail/users/locale/el/LC_MESSAGES/django.po +1 -1
  1043. wagtail/users/locale/en/LC_MESSAGES/django.po +2 -2
  1044. wagtail/users/locale/es/LC_MESSAGES/django.po +1 -1
  1045. wagtail/users/locale/es_419/LC_MESSAGES/django.po +1 -1
  1046. wagtail/users/locale/et/LC_MESSAGES/django.po +1 -1
  1047. wagtail/users/locale/eu/LC_MESSAGES/django.po +1 -1
  1048. wagtail/users/locale/fa/LC_MESSAGES/django.po +1 -1
  1049. wagtail/users/locale/fi/LC_MESSAGES/django.mo +0 -0
  1050. wagtail/users/locale/fi/LC_MESSAGES/django.po +6 -3
  1051. wagtail/users/locale/fr/LC_MESSAGES/django.po +1 -1
  1052. wagtail/users/locale/gl/LC_MESSAGES/django.po +1 -1
  1053. wagtail/users/locale/he_IL/LC_MESSAGES/django.po +1 -1
  1054. wagtail/users/locale/hr_HR/LC_MESSAGES/django.po +1 -1
  1055. wagtail/users/locale/hu/LC_MESSAGES/django.po +1 -1
  1056. wagtail/users/locale/hy/LC_MESSAGES/django.po +1 -1
  1057. wagtail/users/locale/id_ID/LC_MESSAGES/django.po +1 -1
  1058. wagtail/users/locale/is_IS/LC_MESSAGES/django.po +1 -1
  1059. wagtail/users/locale/it/LC_MESSAGES/django.po +1 -1
  1060. wagtail/users/locale/ja/LC_MESSAGES/django.po +1 -1
  1061. wagtail/users/locale/ka/LC_MESSAGES/django.po +1 -1
  1062. wagtail/users/locale/ko/LC_MESSAGES/django.po +1 -1
  1063. wagtail/users/locale/lt/LC_MESSAGES/django.po +1 -1
  1064. wagtail/users/locale/lv/LC_MESSAGES/django.po +1 -1
  1065. wagtail/users/locale/mi/LC_MESSAGES/django.po +1 -1
  1066. wagtail/users/locale/mn/LC_MESSAGES/django.po +1 -1
  1067. wagtail/users/locale/my/LC_MESSAGES/django.po +1 -1
  1068. wagtail/users/locale/nb/LC_MESSAGES/django.po +1 -1
  1069. wagtail/users/locale/nl/LC_MESSAGES/django.mo +0 -0
  1070. wagtail/users/locale/nl/LC_MESSAGES/django.po +7 -4
  1071. wagtail/users/locale/pl/LC_MESSAGES/django.po +1 -1
  1072. wagtail/users/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  1073. wagtail/users/locale/pt_PT/LC_MESSAGES/django.po +1 -1
  1074. wagtail/users/locale/ro/LC_MESSAGES/django.po +1 -1
  1075. wagtail/users/locale/ru/LC_MESSAGES/django.mo +0 -0
  1076. wagtail/users/locale/ru/LC_MESSAGES/django.po +6 -2
  1077. wagtail/users/locale/sk_SK/LC_MESSAGES/django.po +1 -1
  1078. wagtail/users/locale/sl/LC_MESSAGES/django.po +1 -1
  1079. wagtail/users/locale/sv/LC_MESSAGES/django.po +1 -1
  1080. wagtail/users/locale/tet/LC_MESSAGES/django.po +1 -1
  1081. wagtail/users/locale/th/LC_MESSAGES/django.po +1 -1
  1082. wagtail/users/locale/tr/LC_MESSAGES/django.mo +0 -0
  1083. wagtail/users/locale/tr/LC_MESSAGES/django.po +79 -5
  1084. wagtail/users/locale/tr_TR/LC_MESSAGES/django.po +1 -1
  1085. wagtail/users/locale/ug/LC_MESSAGES/django.po +1 -1
  1086. wagtail/users/locale/uk/LC_MESSAGES/django.po +1 -1
  1087. wagtail/users/locale/vi/LC_MESSAGES/django.po +1 -1
  1088. wagtail/users/locale/zh/LC_MESSAGES/django.po +1 -1
  1089. wagtail/users/locale/zh_Hans/LC_MESSAGES/django.po +1 -1
  1090. wagtail/users/locale/zh_Hant/LC_MESSAGES/django.po +1 -1
  1091. wagtail/users/templates/wagtailusers/users/create.html +2 -0
  1092. wagtail/users/templates/wagtailusers/users/edit.html +2 -0
  1093. wagtail/users/tests/test_admin_views.py +4 -0
  1094. wagtail/users/views/users.py +1 -1
  1095. {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/METADATA +8 -7
  1096. {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/RECORD +1102 -1108
  1097. wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +0 -13
  1098. wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +0 -13
  1099. wagtail/search/tests/__init__.py +0 -0
  1100. wagtail/search/tests/elasticsearch_common_tests.py +0 -251
  1101. wagtail/search/tests/test_backends.py +0 -1215
  1102. wagtail/search/tests/test_db_backend.py +0 -62
  1103. wagtail/search/tests/test_elasticsearch7_backend.py +0 -1452
  1104. wagtail/search/tests/test_elasticsearch8_backend.py +0 -15
  1105. wagtail/search/tests/test_index_functions.py +0 -256
  1106. wagtail/search/tests/test_indexed_class.py +0 -157
  1107. wagtail/search/tests/test_mysql_backend.py +0 -192
  1108. wagtail/search/tests/test_postgres_backend.py +0 -210
  1109. wagtail/search/tests/test_queries.py +0 -332
  1110. wagtail/search/tests/test_related_fields.py +0 -102
  1111. wagtail/search/tests/test_sqlite_backend.py +0 -52
  1112. wagtail/test/search/__init__.py +0 -0
  1113. wagtail/test/search/apps.py +0 -9
  1114. wagtail/test/search/fixtures/search.json +0 -545
  1115. wagtail/test/search/migrations/0001_initial.py +0 -146
  1116. wagtail/test/search/migrations/0002_bookunindexed.py +0 -43
  1117. wagtail/test/search/migrations/0003_book_summary.py +0 -18
  1118. wagtail/test/search/migrations/__init__.py +0 -0
  1119. wagtail/test/search/models.py +0 -137
  1120. /wagtail/admin/templates/wagtailadmin/{pages/listing/_ordering_cell.html → tables/ordering_cell.html} +0 -0
  1121. /wagtail/{search/checks.py → checks.py} +0 -0
  1122. {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/WHEEL +0 -0
  1123. {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/entry_points.txt +0 -0
  1124. {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/licenses/LICENSE +0 -0
  1125. {wagtail-7.1.2.dist-info → wagtail-7.2.dist-info}/top_level.txt +0 -0
@@ -1,1452 +0,0 @@
1
- import datetime
2
- import json
3
- import unittest
4
- from unittest import mock
5
-
6
- from django.db.models import Q
7
- from django.test import TestCase
8
-
9
- from wagtail.search.query import MATCH_ALL, Fuzzy, Phrase
10
- from wagtail.test.search import models
11
-
12
- from .elasticsearch_common_tests import ElasticsearchCommonSearchBackendTests
13
-
14
- try:
15
- from elasticsearch import VERSION as ELASTICSEARCH_VERSION
16
- from elasticsearch.serializer import JSONSerializer
17
-
18
- from wagtail.search.backends.elasticsearch7 import Elasticsearch7SearchBackend
19
- except ImportError:
20
- ELASTICSEARCH_VERSION = (0, 0, 0)
21
-
22
-
23
- use_new_elasticsearch_api = ELASTICSEARCH_VERSION >= (7, 15)
24
-
25
- if use_new_elasticsearch_api:
26
- search_query_kwargs = {
27
- "query": "QUERY",
28
- }
29
- else:
30
- search_query_kwargs = {"body": {"query": "QUERY"}}
31
-
32
-
33
- @unittest.skipIf(ELASTICSEARCH_VERSION[0] != 7, "Elasticsearch 7 required")
34
- class TestElasticsearch7SearchBackend(ElasticsearchCommonSearchBackendTests, TestCase):
35
- backend_path = "wagtail.search.backends.elasticsearch7"
36
-
37
-
38
- @unittest.skipIf(ELASTICSEARCH_VERSION[0] != 7, "Elasticsearch 7 required")
39
- class TestElasticsearch7SearchQuery(TestCase):
40
- maxDiff = None
41
-
42
- def assertDictEqual(self, a, b):
43
- default = JSONSerializer().default
44
- self.assertEqual(
45
- json.dumps(a, sort_keys=True, default=default),
46
- json.dumps(b, sort_keys=True, default=default),
47
- )
48
-
49
- @classmethod
50
- def setUpClass(cls):
51
- super().setUpClass()
52
- cls.query_compiler_class = Elasticsearch7SearchBackend.query_compiler_class
53
- cls.autocomplete_query_compiler_class = (
54
- Elasticsearch7SearchBackend.autocomplete_query_compiler_class
55
- )
56
-
57
- def test_simple(self):
58
- # Create a query
59
- query = self.query_compiler_class(models.Book.objects.all(), "Hello")
60
-
61
- # Check it
62
- expected_result = {
63
- "bool": {
64
- "filter": {"match": {"content_type": "searchtests.Book"}},
65
- "must": {
66
- "multi_match": {
67
- "fields": [
68
- "_all_text",
69
- "_all_text_boost_2_0^2.0",
70
- ],
71
- "query": "Hello",
72
- },
73
- },
74
- }
75
- }
76
- self.assertDictEqual(query.get_query(), expected_result)
77
-
78
- def test_simple_autocomplete(self):
79
- # Create a query
80
- query = self.autocomplete_query_compiler_class(
81
- models.Book.objects.all(), "Hello"
82
- )
83
-
84
- # Check it
85
- expected_result = {
86
- "bool": {
87
- "filter": {"match": {"content_type": "searchtests.Book"}},
88
- "must": {
89
- "match": {
90
- "_edgengrams": {
91
- "query": "Hello",
92
- }
93
- },
94
- },
95
- }
96
- }
97
- self.assertDictEqual(query.get_query(), expected_result)
98
-
99
- def test_match_all_autocomplete(self):
100
- # Create a query
101
- query = self.autocomplete_query_compiler_class(
102
- models.Book.objects.all(), MATCH_ALL
103
- )
104
-
105
- # Check it
106
- expected_result = {
107
- "bool": {
108
- "filter": {"match": {"content_type": "searchtests.Book"}},
109
- "must": {"match_all": {}},
110
- }
111
- }
112
- self.assertDictEqual(query.get_query(), expected_result)
113
-
114
- def test_non_supported_queries_autocomplete(self):
115
- # Create a query
116
- query = self.autocomplete_query_compiler_class(
117
- models.Book.objects.all(), Fuzzy("Hello")
118
- )
119
-
120
- # Check it
121
- with self.assertRaises(NotImplementedError):
122
- query.get_query()
123
-
124
- def test_none_query_string(self):
125
- # Create a query
126
- query = self.query_compiler_class(models.Book.objects.all(), MATCH_ALL)
127
-
128
- # Check it
129
- expected_result = {
130
- "bool": {
131
- "filter": {"match": {"content_type": "searchtests.Book"}},
132
- "must": {"match_all": {}},
133
- }
134
- }
135
- self.assertDictEqual(query.get_query(), expected_result)
136
-
137
- def test_and_operator(self):
138
- # Create a query
139
- query = self.query_compiler_class(
140
- models.Book.objects.all(), "Hello", operator="and"
141
- )
142
-
143
- # Check it
144
- expected_result = {
145
- "bool": {
146
- "filter": {"match": {"content_type": "searchtests.Book"}},
147
- "must": {
148
- "multi_match": {
149
- "fields": [
150
- "_all_text",
151
- "_all_text_boost_2_0^2.0",
152
- ],
153
- "query": "Hello",
154
- "operator": "and",
155
- },
156
- },
157
- }
158
- }
159
- self.assertDictEqual(query.get_query(), expected_result)
160
-
161
- def test_filter(self):
162
- # Create a query
163
- query = self.query_compiler_class(
164
- models.Book.objects.filter(title="Test"), "Hello"
165
- )
166
-
167
- # Check it
168
- expected_result = {
169
- "bool": {
170
- "filter": [
171
- {"match": {"content_type": "searchtests.Book"}},
172
- {"term": {"title_filter": "Test"}},
173
- ],
174
- "must": {
175
- "multi_match": {
176
- "fields": [
177
- "_all_text",
178
- "_all_text_boost_2_0^2.0",
179
- ],
180
- "query": "Hello",
181
- },
182
- },
183
- }
184
- }
185
- self.assertDictEqual(query.get_query(), expected_result)
186
-
187
- def test_and_filter(self):
188
- # Create a query
189
- query = self.query_compiler_class(
190
- models.Book.objects.filter(
191
- title="Test", publication_date=datetime.date(2017, 10, 18)
192
- ),
193
- "Hello",
194
- )
195
-
196
- # Check it
197
- expected_result = {
198
- "bool": {
199
- "filter": [
200
- {"match": {"content_type": "searchtests.Book"}},
201
- {
202
- "bool": {
203
- "must": [
204
- {"term": {"publication_date_filter": "2017-10-18"}},
205
- {"term": {"title_filter": "Test"}},
206
- ]
207
- }
208
- },
209
- ],
210
- "must": {
211
- "multi_match": {
212
- "fields": [
213
- "_all_text",
214
- "_all_text_boost_2_0^2.0",
215
- ],
216
- "query": "Hello",
217
- },
218
- },
219
- }
220
- }
221
-
222
- # Make sure field filters are sorted (as they can be in any order which may cause false positives)
223
- query = query.get_query()
224
- field_filters = query["bool"]["filter"][1]["bool"]["must"]
225
- field_filters[:] = sorted(
226
- field_filters, key=lambda f: list(f["term"].keys())[0]
227
- )
228
-
229
- self.assertDictEqual(query, expected_result)
230
-
231
- def test_or_filter(self):
232
- # Create a query
233
- query = self.query_compiler_class(
234
- models.Book.objects.filter(
235
- Q(title="Test") | Q(publication_date=datetime.date(2017, 10, 18))
236
- ),
237
- "Hello",
238
- )
239
-
240
- # Make sure field filters are sorted (as they can be in any order which may cause false positives)
241
- query = query.get_query()
242
- field_filters = query["bool"]["filter"][1]["bool"]["should"]
243
- field_filters[:] = sorted(
244
- field_filters, key=lambda f: list(f["term"].keys())[0]
245
- )
246
-
247
- # Check it
248
- expected_result = {
249
- "bool": {
250
- "filter": [
251
- {"match": {"content_type": "searchtests.Book"}},
252
- {
253
- "bool": {
254
- "should": [
255
- {"term": {"publication_date_filter": "2017-10-18"}},
256
- {"term": {"title_filter": "Test"}},
257
- ]
258
- }
259
- },
260
- ],
261
- "must": {
262
- "multi_match": {
263
- "fields": [
264
- "_all_text",
265
- "_all_text_boost_2_0^2.0",
266
- ],
267
- "query": "Hello",
268
- },
269
- },
270
- }
271
- }
272
- self.assertDictEqual(query, expected_result)
273
-
274
- def test_negated_filter(self):
275
- # Create a query
276
- query = self.query_compiler_class(
277
- models.Book.objects.exclude(publication_date=datetime.date(2017, 10, 18)),
278
- "Hello",
279
- )
280
-
281
- # Check it
282
- expected_result = {
283
- "bool": {
284
- "filter": [
285
- {"match": {"content_type": "searchtests.Book"}},
286
- {
287
- "bool": {
288
- "mustNot": {
289
- "term": {"publication_date_filter": "2017-10-18"}
290
- }
291
- }
292
- },
293
- ],
294
- "must": {
295
- "multi_match": {
296
- "fields": [
297
- "_all_text",
298
- "_all_text_boost_2_0^2.0",
299
- ],
300
- "query": "Hello",
301
- },
302
- },
303
- }
304
- }
305
- self.assertDictEqual(query.get_query(), expected_result)
306
-
307
- def test_fields(self):
308
- # Create a query
309
- query = self.query_compiler_class(
310
- models.Book.objects.all(), "Hello", fields=["title"]
311
- )
312
-
313
- # Check it
314
- expected_result = {
315
- "bool": {
316
- "filter": {"match": {"content_type": "searchtests.Book"}},
317
- "must": {
318
- "match": {
319
- "title": {
320
- "query": "Hello",
321
- "boost": 2.0,
322
- },
323
- },
324
- },
325
- }
326
- }
327
- self.assertDictEqual(query.get_query(), expected_result)
328
-
329
- def test_fields_with_and_operator(self):
330
- # Create a query
331
- query = self.query_compiler_class(
332
- models.Book.objects.all(), "Hello", fields=["title"], operator="and"
333
- )
334
-
335
- # Check it
336
- expected_result = {
337
- "bool": {
338
- "filter": {"match": {"content_type": "searchtests.Book"}},
339
- "must": {
340
- "match": {
341
- "title": {
342
- "query": "Hello",
343
- "boost": 2.0,
344
- "operator": "and",
345
- }
346
- },
347
- },
348
- }
349
- }
350
- self.assertDictEqual(query.get_query(), expected_result)
351
-
352
- def test_multiple_fields(self):
353
- # Create a query
354
- query = self.query_compiler_class(
355
- models.Book.objects.all(), "Hello", fields=["title", "summary"]
356
- )
357
-
358
- # Check it
359
- expected_result = {
360
- "bool": {
361
- "filter": {"match": {"content_type": "searchtests.Book"}},
362
- "must": {
363
- "multi_match": {
364
- "fields": [
365
- "title^2.0",
366
- "summary",
367
- ],
368
- "query": "Hello",
369
- }
370
- },
371
- }
372
- }
373
- self.assertDictEqual(query.get_query(), expected_result)
374
-
375
- def test_multiple_fields_with_and_operator(self):
376
- # Create a query
377
- query = self.query_compiler_class(
378
- models.Book.objects.all(),
379
- "Hello",
380
- fields=["title", "summary"],
381
- operator="and",
382
- )
383
-
384
- # Check it
385
- expected_result = {
386
- "bool": {
387
- "filter": {"match": {"content_type": "searchtests.Book"}},
388
- "must": {
389
- "multi_match": {
390
- "fields": [
391
- "title^2.0",
392
- "summary",
393
- ],
394
- "query": "Hello",
395
- "operator": "and",
396
- }
397
- },
398
- }
399
- }
400
- self.assertDictEqual(query.get_query(), expected_result)
401
-
402
- def test_exact_lookup(self):
403
- # Create a query
404
- query = self.query_compiler_class(
405
- models.Book.objects.filter(title__exact="Test"), "Hello"
406
- )
407
-
408
- # Check it
409
- expected_result = {
410
- "bool": {
411
- "filter": [
412
- {"match": {"content_type": "searchtests.Book"}},
413
- {"term": {"title_filter": "Test"}},
414
- ],
415
- "must": {
416
- "multi_match": {
417
- "fields": [
418
- "_all_text",
419
- "_all_text_boost_2_0^2.0",
420
- ],
421
- "query": "Hello",
422
- },
423
- },
424
- }
425
- }
426
- self.assertDictEqual(query.get_query(), expected_result)
427
-
428
- def test_none_lookup(self):
429
- # Create a query
430
- query = self.query_compiler_class(
431
- models.Book.objects.filter(title=None), "Hello"
432
- )
433
-
434
- # Check it
435
- expected_result = {
436
- "bool": {
437
- "filter": [
438
- {"match": {"content_type": "searchtests.Book"}},
439
- {"bool": {"mustNot": {"exists": {"field": "title_filter"}}}},
440
- ],
441
- "must": {
442
- "multi_match": {
443
- "fields": [
444
- "_all_text",
445
- "_all_text_boost_2_0^2.0",
446
- ],
447
- "query": "Hello",
448
- },
449
- },
450
- }
451
- }
452
- self.assertDictEqual(query.get_query(), expected_result)
453
-
454
- def test_isnull_true_lookup(self):
455
- # Create a query
456
- query = self.query_compiler_class(
457
- models.Book.objects.filter(title__isnull=True), "Hello"
458
- )
459
-
460
- # Check it
461
- expected_result = {
462
- "bool": {
463
- "filter": [
464
- {"match": {"content_type": "searchtests.Book"}},
465
- {"bool": {"mustNot": {"exists": {"field": "title_filter"}}}},
466
- ],
467
- "must": {
468
- "multi_match": {
469
- "fields": [
470
- "_all_text",
471
- "_all_text_boost_2_0^2.0",
472
- ],
473
- "query": "Hello",
474
- },
475
- },
476
- }
477
- }
478
- self.assertDictEqual(query.get_query(), expected_result)
479
-
480
- def test_isnull_false_lookup(self):
481
- # Create a query
482
- query = self.query_compiler_class(
483
- models.Book.objects.filter(title__isnull=False), "Hello"
484
- )
485
-
486
- # Check it
487
- expected_result = {
488
- "bool": {
489
- "filter": [
490
- {"match": {"content_type": "searchtests.Book"}},
491
- {"exists": {"field": "title_filter"}},
492
- ],
493
- "must": {
494
- "multi_match": {
495
- "fields": [
496
- "_all_text",
497
- "_all_text_boost_2_0^2.0",
498
- ],
499
- "query": "Hello",
500
- },
501
- },
502
- }
503
- }
504
- self.assertDictEqual(query.get_query(), expected_result)
505
-
506
- def test_startswith_lookup(self):
507
- # Create a query
508
- query = self.query_compiler_class(
509
- models.Book.objects.filter(title__startswith="Test"), "Hello"
510
- )
511
-
512
- # Check it
513
- expected_result = {
514
- "bool": {
515
- "filter": [
516
- {"match": {"content_type": "searchtests.Book"}},
517
- {"prefix": {"title_filter": "Test"}},
518
- ],
519
- "must": {
520
- "multi_match": {
521
- "fields": [
522
- "_all_text",
523
- "_all_text_boost_2_0^2.0",
524
- ],
525
- "query": "Hello",
526
- },
527
- },
528
- }
529
- }
530
- self.assertDictEqual(query.get_query(), expected_result)
531
-
532
- def test_gt_lookup(self):
533
- # This also tests conversion of python dates to strings
534
-
535
- # Create a query
536
- query = self.query_compiler_class(
537
- models.Book.objects.filter(
538
- publication_date__gt=datetime.datetime(2014, 4, 29)
539
- ),
540
- "Hello",
541
- )
542
-
543
- # Check it
544
- expected_result = {
545
- "bool": {
546
- "filter": [
547
- {"match": {"content_type": "searchtests.Book"}},
548
- {"range": {"publication_date_filter": {"gt": "2014-04-29"}}},
549
- ],
550
- "must": {
551
- "multi_match": {
552
- "fields": [
553
- "_all_text",
554
- "_all_text_boost_2_0^2.0",
555
- ],
556
- "query": "Hello",
557
- },
558
- },
559
- }
560
- }
561
- self.assertDictEqual(query.get_query(), expected_result)
562
-
563
- def test_lt_lookup(self):
564
- # Create a query
565
- query = self.query_compiler_class(
566
- models.Book.objects.filter(
567
- publication_date__lt=datetime.datetime(2014, 4, 29)
568
- ),
569
- "Hello",
570
- )
571
-
572
- # Check it
573
- expected_result = {
574
- "bool": {
575
- "filter": [
576
- {"match": {"content_type": "searchtests.Book"}},
577
- {"range": {"publication_date_filter": {"lt": "2014-04-29"}}},
578
- ],
579
- "must": {
580
- "multi_match": {
581
- "fields": [
582
- "_all_text",
583
- "_all_text_boost_2_0^2.0",
584
- ],
585
- "query": "Hello",
586
- },
587
- },
588
- }
589
- }
590
- self.assertDictEqual(query.get_query(), expected_result)
591
-
592
- def test_gte_lookup(self):
593
- # Create a query
594
- query = self.query_compiler_class(
595
- models.Book.objects.filter(
596
- publication_date__gte=datetime.datetime(2014, 4, 29)
597
- ),
598
- "Hello",
599
- )
600
-
601
- # Check it
602
- expected_result = {
603
- "bool": {
604
- "filter": [
605
- {"match": {"content_type": "searchtests.Book"}},
606
- {"range": {"publication_date_filter": {"gte": "2014-04-29"}}},
607
- ],
608
- "must": {
609
- "multi_match": {
610
- "fields": [
611
- "_all_text",
612
- "_all_text_boost_2_0^2.0",
613
- ],
614
- "query": "Hello",
615
- },
616
- },
617
- }
618
- }
619
- self.assertDictEqual(query.get_query(), expected_result)
620
-
621
- def test_lte_lookup(self):
622
- # Create a query
623
- query = self.query_compiler_class(
624
- models.Book.objects.filter(
625
- publication_date__lte=datetime.datetime(2014, 4, 29)
626
- ),
627
- "Hello",
628
- )
629
-
630
- # Check it
631
- expected_result = {
632
- "bool": {
633
- "filter": [
634
- {"match": {"content_type": "searchtests.Book"}},
635
- {"range": {"publication_date_filter": {"lte": "2014-04-29"}}},
636
- ],
637
- "must": {
638
- "multi_match": {
639
- "fields": [
640
- "_all_text",
641
- "_all_text_boost_2_0^2.0",
642
- ],
643
- "query": "Hello",
644
- },
645
- },
646
- }
647
- }
648
- self.assertDictEqual(query.get_query(), expected_result)
649
-
650
- def test_range_lookup(self):
651
- start_date = datetime.datetime(2014, 4, 29)
652
- end_date = datetime.datetime(2014, 8, 19)
653
-
654
- # Create a query
655
- query = self.query_compiler_class(
656
- models.Book.objects.filter(publication_date__range=(start_date, end_date)),
657
- "Hello",
658
- )
659
-
660
- # Check it
661
- expected_result = {
662
- "bool": {
663
- "filter": [
664
- {"match": {"content_type": "searchtests.Book"}},
665
- {
666
- "range": {
667
- "publication_date_filter": {
668
- "gte": "2014-04-29",
669
- "lte": "2014-08-19",
670
- }
671
- }
672
- },
673
- ],
674
- "must": {
675
- "multi_match": {
676
- "fields": [
677
- "_all_text",
678
- "_all_text_boost_2_0^2.0",
679
- ],
680
- "query": "Hello",
681
- },
682
- },
683
- }
684
- }
685
- self.assertDictEqual(query.get_query(), expected_result)
686
-
687
- def test_custom_ordering(self):
688
- # Create a query
689
- query = self.query_compiler_class(
690
- models.Book.objects.order_by("publication_date"),
691
- "Hello",
692
- order_by_relevance=False,
693
- )
694
-
695
- # Check it
696
- expected_result = [{"publication_date_filter": "asc"}]
697
- self.assertDictEqual(query.get_sort(), expected_result)
698
-
699
- def test_custom_ordering_reversed(self):
700
- # Create a query
701
- query = self.query_compiler_class(
702
- models.Book.objects.order_by("-publication_date"),
703
- "Hello",
704
- order_by_relevance=False,
705
- )
706
-
707
- # Check it
708
- expected_result = [{"publication_date_filter": "desc"}]
709
- self.assertDictEqual(query.get_sort(), expected_result)
710
-
711
- def test_custom_ordering_multiple(self):
712
- # Create a query
713
- query = self.query_compiler_class(
714
- models.Book.objects.order_by("publication_date", "number_of_pages"),
715
- "Hello",
716
- order_by_relevance=False,
717
- )
718
-
719
- # Check it
720
- expected_result = [
721
- {"publication_date_filter": "asc"},
722
- {"number_of_pages_filter": "asc"},
723
- ]
724
- self.assertDictEqual(query.get_sort(), expected_result)
725
-
726
- def test_phrase_query(self):
727
- # Create a query
728
- query_compiler = self.query_compiler_class(
729
- models.Book.objects.all(), Phrase("Hello world")
730
- )
731
-
732
- # Check it
733
- expected_result = {
734
- "multi_match": {
735
- "fields": [
736
- "_all_text",
737
- "_all_text_boost_2_0^2.0",
738
- ],
739
- "query": "Hello world",
740
- "type": "phrase",
741
- },
742
- }
743
- self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
744
-
745
- def test_phrase_query_multiple_fields(self):
746
- # Create a query
747
- query_compiler = self.query_compiler_class(
748
- models.Book.objects.all(),
749
- Phrase("Hello world"),
750
- fields=["title", "summary"],
751
- )
752
-
753
- # Check it
754
- expected_result = {
755
- "multi_match": {
756
- "query": "Hello world",
757
- "fields": [
758
- "title^2.0",
759
- "summary",
760
- ],
761
- "type": "phrase",
762
- }
763
- }
764
- self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
765
-
766
- def test_phrase_query_single_field(self):
767
- # Create a query
768
- query_compiler = self.query_compiler_class(
769
- models.Book.objects.all(), Phrase("Hello world"), fields=["title"]
770
- )
771
-
772
- # Check it
773
- expected_result = {
774
- "match_phrase": {
775
- "title": {
776
- "query": "Hello world",
777
- "boost": 2.0,
778
- },
779
- },
780
- }
781
- self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
782
-
783
- def test_fuzzy_query(self):
784
- # Create a query
785
- query_compiler = self.query_compiler_class(
786
- models.Book.objects.all(),
787
- Fuzzy("Hello world"),
788
- )
789
-
790
- # Check it
791
- expected_result = {
792
- "multi_match": {
793
- "fields": [
794
- "_all_text",
795
- "_all_text_boost_2_0^2.0",
796
- ],
797
- "query": "Hello world",
798
- "fuzziness": "AUTO",
799
- }
800
- }
801
- self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
802
-
803
- def test_fuzzy_query_single_field(self):
804
- # Create a query
805
- query_compiler = self.query_compiler_class(
806
- models.Book.objects.all(),
807
- Fuzzy("Hello world"),
808
- fields=["title"],
809
- )
810
-
811
- # Check it
812
- expected_result = {
813
- "match": {
814
- "title": {
815
- "query": "Hello world",
816
- "fuzziness": "AUTO",
817
- "boost": 2.0,
818
- },
819
- }
820
- }
821
- self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
822
-
823
- def test_fuzzy_query_multiple_fields(self):
824
- # Create a query
825
- query_compiler = self.query_compiler_class(
826
- models.Book.objects.all(),
827
- Fuzzy("Hello world"),
828
- fields=["title", "summary"],
829
- )
830
-
831
- expected_result = {
832
- "multi_match": {
833
- "fields": [
834
- "title^2.0",
835
- "summary",
836
- ],
837
- "query": "Hello world",
838
- "fuzziness": "AUTO",
839
- }
840
- }
841
- self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
842
-
843
- def test_fuzzy_query_with_operator(self):
844
- # Create a query
845
- query_compiler = self.query_compiler_class(
846
- models.Book.objects.all(),
847
- Fuzzy("Hello world", operator="and"),
848
- )
849
-
850
- # Check it
851
- expected_result = {
852
- "multi_match": {
853
- "fields": [
854
- "_all_text",
855
- "_all_text_boost_2_0^2.0",
856
- ],
857
- "query": "Hello world",
858
- "fuzziness": "AUTO",
859
- "operator": "and",
860
- }
861
- }
862
- self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
863
-
864
- def test_year_filter(self):
865
- # Create a query
866
- query_compiler = self.query_compiler_class(
867
- models.Book.objects.filter(publication_date__year__lt=1900), "Hello"
868
- )
869
-
870
- # Check it
871
- expected_result = {
872
- "bool": {
873
- "filter": [
874
- {"match": {"content_type": "searchtests.Book"}},
875
- {"range": {"publication_date_filter": {"lt": "1900-01-01"}}},
876
- ],
877
- "must": {
878
- "multi_match": {
879
- "fields": [
880
- "_all_text",
881
- "_all_text_boost_2_0^2.0",
882
- ],
883
- "query": "Hello",
884
- }
885
- },
886
- }
887
- }
888
- self.assertDictEqual(query_compiler.get_query(), expected_result)
889
-
890
-
891
- @unittest.skipIf(ELASTICSEARCH_VERSION[0] != 7, "Elasticsearch 7 required")
892
- class TestElasticsearch7SearchResults(TestCase):
893
- fixtures = ["search"]
894
-
895
- def assertDictEqual(self, a, b):
896
- default = JSONSerializer().default
897
- self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps)
898
-
899
- def get_results(self):
900
- backend = Elasticsearch7SearchBackend({})
901
- query = mock.MagicMock()
902
- query.queryset = models.Book.objects.all()
903
- query.get_query.return_value = "QUERY"
904
- query.get_sort.return_value = None
905
- return backend.results_class(backend, query)
906
-
907
- def construct_search_response(self, results):
908
- return {
909
- "_shards": {"failed": 0, "successful": 5, "total": 5},
910
- "hits": {
911
- "hits": [
912
- {
913
- "_id": "searchtests_book:" + str(result),
914
- "_index": "wagtail",
915
- "_score": 1,
916
- "_type": "searchtests_book",
917
- "fields": {
918
- "pk": [str(result)],
919
- },
920
- }
921
- for result in results
922
- ],
923
- "max_score": 1,
924
- "total": len(results),
925
- },
926
- "timed_out": False,
927
- "took": 2,
928
- }
929
-
930
- @mock.patch("elasticsearch.Elasticsearch.search")
931
- def test_basic_search(self, search):
932
- search.return_value = self.construct_search_response([])
933
- results = self.get_results()
934
-
935
- list(results) # Performs search
936
-
937
- search.assert_any_call(
938
- _source=False,
939
- stored_fields="pk",
940
- index="wagtail__searchtests_book",
941
- scroll="2m",
942
- size=100,
943
- **search_query_kwargs,
944
- )
945
-
946
- @mock.patch("elasticsearch.Elasticsearch.search")
947
- def test_get_single_item(self, search):
948
- # Need to return something to prevent index error
949
- search.return_value = self.construct_search_response([1])
950
- results = self.get_results()
951
-
952
- results[10] # Performs search
953
-
954
- search.assert_any_call(
955
- from_=10,
956
- _source=False,
957
- stored_fields="pk",
958
- index="wagtail__searchtests_book",
959
- size=1,
960
- **search_query_kwargs,
961
- )
962
-
963
- @mock.patch("elasticsearch.Elasticsearch.search")
964
- def test_slice_results(self, search):
965
- search.return_value = self.construct_search_response([])
966
- results = self.get_results()[1:4]
967
-
968
- list(results) # Performs search
969
-
970
- search.assert_any_call(
971
- from_=1,
972
- _source=False,
973
- stored_fields="pk",
974
- index="wagtail__searchtests_book",
975
- size=3,
976
- **search_query_kwargs,
977
- )
978
-
979
- @mock.patch("elasticsearch.Elasticsearch.search")
980
- def test_slice_results_multiple_times(self, search):
981
- search.return_value = self.construct_search_response([])
982
- results = self.get_results()[10:][:10]
983
-
984
- list(results) # Performs search
985
-
986
- search.assert_any_call(
987
- from_=10,
988
- _source=False,
989
- stored_fields="pk",
990
- index="wagtail__searchtests_book",
991
- size=10,
992
- **search_query_kwargs,
993
- )
994
-
995
- @mock.patch("elasticsearch.Elasticsearch.search")
996
- def test_slice_results_and_get_item(self, search):
997
- # Need to return something to prevent index error
998
- search.return_value = self.construct_search_response([1])
999
- results = self.get_results()[10:]
1000
-
1001
- results[10] # Performs search
1002
-
1003
- search.assert_any_call(
1004
- from_=20,
1005
- _source=False,
1006
- stored_fields="pk",
1007
- index="wagtail__searchtests_book",
1008
- size=1,
1009
- **search_query_kwargs,
1010
- )
1011
-
1012
- @mock.patch("elasticsearch.Elasticsearch.search")
1013
- def test_result_returned(self, search):
1014
- search.return_value = self.construct_search_response([1])
1015
- results = self.get_results()
1016
-
1017
- self.assertEqual(results[0], models.Book.objects.get(id=1))
1018
-
1019
- @mock.patch("elasticsearch.Elasticsearch.search")
1020
- def test_len_1(self, search):
1021
- search.return_value = self.construct_search_response([1])
1022
- results = self.get_results()
1023
-
1024
- self.assertEqual(len(results), 1)
1025
-
1026
- @mock.patch("elasticsearch.Elasticsearch.search")
1027
- def test_len_2(self, search):
1028
- search.return_value = self.construct_search_response([1, 2])
1029
- results = self.get_results()
1030
-
1031
- self.assertEqual(len(results), 2)
1032
-
1033
- @mock.patch("elasticsearch.Elasticsearch.search")
1034
- def test_duplicate_results(self, search): # Duplicates will not be removed
1035
- search.return_value = self.construct_search_response([1, 1])
1036
- results = list(
1037
- self.get_results()
1038
- ) # Must cast to list so we only create one query
1039
-
1040
- self.assertEqual(len(results), 2)
1041
- self.assertEqual(results[0], models.Book.objects.get(id=1))
1042
- self.assertEqual(results[1], models.Book.objects.get(id=1))
1043
-
1044
- @mock.patch("elasticsearch.Elasticsearch.search")
1045
- def test_result_order(self, search):
1046
- search.return_value = self.construct_search_response([1, 2, 3])
1047
- results = list(
1048
- self.get_results()
1049
- ) # Must cast to list so we only create one query
1050
-
1051
- self.assertEqual(results[0], models.Book.objects.get(id=1))
1052
- self.assertEqual(results[1], models.Book.objects.get(id=2))
1053
- self.assertEqual(results[2], models.Book.objects.get(id=3))
1054
-
1055
- @mock.patch("elasticsearch.Elasticsearch.search")
1056
- def test_result_order_2(self, search):
1057
- search.return_value = self.construct_search_response([3, 2, 1])
1058
- results = list(
1059
- self.get_results()
1060
- ) # Must cast to list so we only create one query
1061
-
1062
- self.assertEqual(results[0], models.Book.objects.get(id=3))
1063
- self.assertEqual(results[1], models.Book.objects.get(id=2))
1064
- self.assertEqual(results[2], models.Book.objects.get(id=1))
1065
-
1066
-
1067
- @unittest.skipIf(ELASTICSEARCH_VERSION[0] != 7, "Elasticsearch 7 required")
1068
- class TestElasticsearch7Mapping(TestCase):
1069
- fixtures = ["search"]
1070
-
1071
- maxDiff = None
1072
-
1073
- def assertDictEqual(self, a, b):
1074
- default = JSONSerializer().default
1075
- self.assertEqual(
1076
- json.dumps(a, sort_keys=True, default=default),
1077
- json.dumps(b, sort_keys=True, default=default),
1078
- )
1079
-
1080
- def setUp(self):
1081
- # Create ES mapping
1082
- self.es_mapping = Elasticsearch7SearchBackend.mapping_class(models.Book)
1083
-
1084
- # Create ES document
1085
- self.obj = models.Book.objects.get(id=4)
1086
-
1087
- def test_get_document_type(self):
1088
- self.assertEqual(self.es_mapping.get_document_type(), "doc")
1089
-
1090
- def test_get_mapping(self):
1091
- # Build mapping
1092
- mapping = self.es_mapping.get_mapping()
1093
-
1094
- # Check
1095
- expected_result = {
1096
- "properties": {
1097
- "pk": {"type": "keyword", "store": True},
1098
- "content_type": {"type": "keyword"},
1099
- "_all_text": {"type": "text"},
1100
- "_all_text_boost_2_0": {"type": "text"},
1101
- "_edgengrams": {
1102
- "analyzer": "edgengram_analyzer",
1103
- "search_analyzer": "standard",
1104
- "type": "text",
1105
- },
1106
- "title": {
1107
- "type": "text",
1108
- "copy_to": ["_all_text", "_all_text_boost_2_0"],
1109
- },
1110
- "title_edgengrams": {
1111
- "type": "text",
1112
- "analyzer": "edgengram_analyzer",
1113
- "search_analyzer": "standard",
1114
- },
1115
- "title_filter": {"type": "keyword"},
1116
- "authors": {
1117
- "type": "nested",
1118
- "properties": {
1119
- "name": {"type": "text", "copy_to": "_all_text"},
1120
- "name_edgengrams": {
1121
- "analyzer": "edgengram_analyzer",
1122
- "search_analyzer": "standard",
1123
- "type": "text",
1124
- },
1125
- "date_of_birth_filter": {"type": "date"},
1126
- },
1127
- },
1128
- "authors_filter": {"type": "integer"},
1129
- "publication_date_filter": {"type": "date"},
1130
- "summary": {"copy_to": "_all_text", "type": "text"},
1131
- "number_of_pages_filter": {"type": "integer"},
1132
- "tags": {
1133
- "type": "nested",
1134
- "properties": {
1135
- "name": {"type": "text", "copy_to": "_all_text"},
1136
- "slug_filter": {"type": "keyword"},
1137
- },
1138
- },
1139
- "tags_filter": {"type": "integer"},
1140
- }
1141
- }
1142
-
1143
- self.assertDictEqual(mapping, expected_result)
1144
-
1145
- def test_get_document_id(self):
1146
- self.assertEqual(self.es_mapping.get_document_id(self.obj), str(self.obj.pk))
1147
-
1148
- def test_get_document(self):
1149
- # Get document
1150
- document = self.es_mapping.get_document(self.obj)
1151
-
1152
- # Sort edgengrams
1153
- if "_edgengrams" in document:
1154
- document["_edgengrams"].sort()
1155
-
1156
- # Check
1157
- expected_result = {
1158
- "pk": "4",
1159
- "content_type": ["searchtests.Book"],
1160
- "_edgengrams": [
1161
- "J. R. R. Tolkien",
1162
- "The Fellowship of the Ring",
1163
- ],
1164
- "title": "The Fellowship of the Ring",
1165
- "title_edgengrams": "The Fellowship of the Ring",
1166
- "title_filter": "The Fellowship of the Ring",
1167
- "authors": [
1168
- {
1169
- "name": "J. R. R. Tolkien",
1170
- "name_edgengrams": "J. R. R. Tolkien",
1171
- "date_of_birth_filter": datetime.date(1892, 1, 3),
1172
- }
1173
- ],
1174
- "authors_filter": [2],
1175
- "publication_date_filter": datetime.date(1954, 7, 29),
1176
- "summary": "",
1177
- "number_of_pages_filter": 423,
1178
- "tags": [],
1179
- "tags_filter": [],
1180
- }
1181
-
1182
- self.assertDictEqual(document, expected_result)
1183
-
1184
-
1185
- @unittest.skipIf(ELASTICSEARCH_VERSION[0] != 7, "Elasticsearch 7 required")
1186
- class TestElasticsearch7MappingInheritance(TestCase):
1187
- fixtures = ["search"]
1188
- maxDiff = None
1189
-
1190
- def assertDictEqual(self, a, b):
1191
- default = JSONSerializer().default
1192
- self.assertEqual(
1193
- json.dumps(a, sort_keys=True, default=default),
1194
- json.dumps(b, sort_keys=True, default=default),
1195
- )
1196
-
1197
- def setUp(self):
1198
- # Create ES mapping
1199
- self.es_mapping = Elasticsearch7SearchBackend.mapping_class(models.Novel)
1200
-
1201
- self.obj = models.Novel.objects.get(id=4)
1202
-
1203
- def test_get_document_type(self):
1204
- self.assertEqual(self.es_mapping.get_document_type(), "doc")
1205
-
1206
- def test_get_mapping(self):
1207
- # Build mapping
1208
- mapping = self.es_mapping.get_mapping()
1209
-
1210
- # Check
1211
- expected_result = {
1212
- "properties": {
1213
- # New
1214
- "searchtests_novel__setting": {
1215
- "type": "text",
1216
- "copy_to": "_all_text",
1217
- },
1218
- "searchtests_novel__setting_edgengrams": {
1219
- "type": "text",
1220
- "analyzer": "edgengram_analyzer",
1221
- "search_analyzer": "standard",
1222
- },
1223
- "searchtests_novel__protagonist": {
1224
- "type": "nested",
1225
- "properties": {
1226
- "name": {
1227
- "type": "text",
1228
- "copy_to": ["_all_text", "_all_text_boost_0_5"],
1229
- },
1230
- "novel_id_filter": {"type": "integer"},
1231
- },
1232
- },
1233
- "searchtests_novel__protagonist_id_filter": {"type": "integer"},
1234
- "searchtests_novel__characters": {
1235
- "type": "nested",
1236
- "properties": {
1237
- "name": {
1238
- "type": "text",
1239
- "copy_to": ["_all_text", "_all_text_boost_0_25"],
1240
- },
1241
- },
1242
- },
1243
- # Inherited
1244
- "pk": {"type": "keyword", "store": True},
1245
- "content_type": {"type": "keyword"},
1246
- "_all_text": {"type": "text"},
1247
- "_all_text_boost_0_25": {"type": "text"},
1248
- "_all_text_boost_0_5": {"type": "text"},
1249
- "_all_text_boost_2_0": {"type": "text"},
1250
- "_edgengrams": {
1251
- "analyzer": "edgengram_analyzer",
1252
- "search_analyzer": "standard",
1253
- "type": "text",
1254
- },
1255
- "title": {
1256
- "type": "text",
1257
- "copy_to": ["_all_text", "_all_text_boost_2_0"],
1258
- },
1259
- "title_edgengrams": {
1260
- "type": "text",
1261
- "analyzer": "edgengram_analyzer",
1262
- "search_analyzer": "standard",
1263
- },
1264
- "title_filter": {"type": "keyword"},
1265
- "authors": {
1266
- "type": "nested",
1267
- "properties": {
1268
- "name": {"type": "text", "copy_to": "_all_text"},
1269
- "name_edgengrams": {
1270
- "analyzer": "edgengram_analyzer",
1271
- "search_analyzer": "standard",
1272
- "type": "text",
1273
- },
1274
- "date_of_birth_filter": {"type": "date"},
1275
- },
1276
- },
1277
- "authors_filter": {"type": "integer"},
1278
- "publication_date_filter": {"type": "date"},
1279
- "number_of_pages_filter": {"type": "integer"},
1280
- "summary": {"copy_to": "_all_text", "type": "text"},
1281
- "tags": {
1282
- "type": "nested",
1283
- "properties": {
1284
- "name": {"type": "text", "copy_to": "_all_text"},
1285
- "slug_filter": {"type": "keyword"},
1286
- },
1287
- },
1288
- "tags_filter": {"type": "integer"},
1289
- }
1290
- }
1291
-
1292
- self.assertDictEqual(mapping, expected_result)
1293
-
1294
- def test_get_document_id(self):
1295
- # This must be tests_searchtest instead of 'tests_searchtest_tests_searchtestchild'
1296
- # as it uses the contents base content type name.
1297
- # This prevents the same object being accidentally indexed twice.
1298
- self.assertEqual(self.es_mapping.get_document_id(self.obj), str(self.obj.pk))
1299
-
1300
- def test_get_document(self):
1301
- # Build document
1302
- document = self.es_mapping.get_document(self.obj)
1303
-
1304
- # Sort edgengrams
1305
- if "_edgengrams" in document:
1306
- document["_edgengrams"].sort()
1307
-
1308
- # Sort characters
1309
- if "searchtests_novel__characters" in document:
1310
- document["searchtests_novel__characters"].sort(key=lambda c: c["name"])
1311
-
1312
- # Check
1313
- expected_result = {
1314
- # New
1315
- "searchtests_novel__setting": "Middle Earth",
1316
- "searchtests_novel__setting_edgengrams": "Middle Earth",
1317
- "searchtests_novel__protagonist": {
1318
- "name": "Frodo Baggins",
1319
- "novel_id_filter": 4,
1320
- },
1321
- "searchtests_novel__protagonist_id_filter": 8,
1322
- "searchtests_novel__characters": [
1323
- {"name": "Bilbo Baggins"},
1324
- {"name": "Frodo Baggins"},
1325
- {"name": "Gandalf"},
1326
- ],
1327
- # Changed
1328
- "content_type": ["searchtests.Novel", "searchtests.Book"],
1329
- "_edgengrams": [
1330
- "J. R. R. Tolkien",
1331
- "Middle Earth",
1332
- "The Fellowship of the Ring",
1333
- ],
1334
- # Inherited
1335
- "pk": "4",
1336
- "title": "The Fellowship of the Ring",
1337
- "title_edgengrams": "The Fellowship of the Ring",
1338
- "title_filter": "The Fellowship of the Ring",
1339
- "authors": [
1340
- {
1341
- "name": "J. R. R. Tolkien",
1342
- "name_edgengrams": "J. R. R. Tolkien",
1343
- "date_of_birth_filter": datetime.date(1892, 1, 3),
1344
- }
1345
- ],
1346
- "authors_filter": [2],
1347
- "publication_date_filter": datetime.date(1954, 7, 29),
1348
- "number_of_pages_filter": 423,
1349
- "summary": "",
1350
- "tags": [],
1351
- "tags_filter": [],
1352
- }
1353
-
1354
- self.assertDictEqual(document, expected_result)
1355
-
1356
-
1357
- @unittest.skipIf(ELASTICSEARCH_VERSION[0] != 7, "Elasticsearch 7 required")
1358
- @mock.patch("wagtail.search.backends.elasticsearch7.Elasticsearch")
1359
- class TestBackendConfiguration(TestCase):
1360
- def test_default_settings(self, Elasticsearch):
1361
- Elasticsearch7SearchBackend(params={})
1362
-
1363
- Elasticsearch.assert_called_with(
1364
- hosts=[
1365
- {
1366
- "host": "localhost",
1367
- "port": 9200,
1368
- "url_prefix": "",
1369
- "use_ssl": False,
1370
- "verify_certs": False,
1371
- "http_auth": None,
1372
- }
1373
- ],
1374
- timeout=10,
1375
- )
1376
-
1377
- def test_hosts(self, Elasticsearch):
1378
- Elasticsearch7SearchBackend(
1379
- params={
1380
- "HOSTS": [
1381
- {
1382
- "host": "127.0.0.1",
1383
- "port": 9300,
1384
- "use_ssl": True,
1385
- "verify_certs": True,
1386
- }
1387
- ]
1388
- }
1389
- )
1390
-
1391
- Elasticsearch.assert_called_with(
1392
- hosts=[
1393
- {
1394
- "host": "127.0.0.1",
1395
- "port": 9300,
1396
- "use_ssl": True,
1397
- "verify_certs": True,
1398
- }
1399
- ],
1400
- timeout=10,
1401
- )
1402
-
1403
- def test_urls(self, Elasticsearch):
1404
- # This test backwards compatibility with old URLS setting
1405
- Elasticsearch7SearchBackend(
1406
- params={
1407
- "URLS": [
1408
- "http://localhost:12345",
1409
- "https://127.0.0.1:54321",
1410
- "http://username:password@elasticsearch.mysite.com",
1411
- "https://elasticsearch.mysite.com/hello",
1412
- ],
1413
- }
1414
- )
1415
-
1416
- Elasticsearch.assert_called_with(
1417
- hosts=[
1418
- {
1419
- "host": "localhost",
1420
- "port": 12345,
1421
- "url_prefix": "",
1422
- "use_ssl": False,
1423
- "verify_certs": False,
1424
- "http_auth": None,
1425
- },
1426
- {
1427
- "host": "127.0.0.1",
1428
- "port": 54321,
1429
- "url_prefix": "",
1430
- "use_ssl": True,
1431
- "verify_certs": True,
1432
- "http_auth": None,
1433
- },
1434
- {
1435
- "host": "elasticsearch.mysite.com",
1436
- "port": 80,
1437
- "url_prefix": "",
1438
- "use_ssl": False,
1439
- "verify_certs": False,
1440
- "http_auth": ("username", "password"),
1441
- },
1442
- {
1443
- "host": "elasticsearch.mysite.com",
1444
- "port": 443,
1445
- "url_prefix": "/hello",
1446
- "use_ssl": True,
1447
- "verify_certs": True,
1448
- "http_auth": None,
1449
- },
1450
- ],
1451
- timeout=10,
1452
- )