From f2cc2cb2fffeb0c40939714b5c150e826fc6250d Mon Sep 17 00:00:00 2001
From: Saurabh Kumar <theskumar@users.noreply.github.com>
Date: Tue, 9 May 2023 13:01:23 +0530
Subject: [PATCH] Upgrade Wagtail to 4.2 (#3045)

Fixes #3018

- Update requirements - `wagtail` and `wagtail-cache`
- Update `BaseSetting` to `BaseSiteSettings`
- Fix Category StreamBlock at hypha/apply/categories/blocks.py
- Add migration changes
- Add `wagtail_reference_index_ignore = True` to models (See [this
issue](https://github.com/wagtail/wagtail/issues/9731) on wagtail for
more info)
- Use checkboxes when selecting reviewers for a Round and a Lab
- Update `ReadOnlyPanel` to use `render_html()` method instead of
`render_as_object()`

---------

Co-authored-by: Fredrik Jonsson <frjo@xdeb.org>
---
 .vscode/settings.json                         |  6 +-
 hypha/apply/activity/models.py                |  3 +
 hypha/apply/categories/blocks.py              | 51 +++++++--------
 hypha/apply/determinations/models.py          | 12 +++-
 hypha/apply/funds/admin_views.py              | 20 ------
 hypha/apply/funds/edit_handlers.py            | 28 ++++-----
 hypha/apply/funds/forms.py                    | 62 ++++++++++---------
 .../migrations/0110_auto_20230418_0644.py     | 28 +++++++++
 .../funds/models/application_revisions.py     |  2 +
 hypha/apply/funds/models/applications.py      | 13 ++--
 .../apply/funds/models/assigned_reviewers.py  |  3 +
 hypha/apply/funds/models/forms.py             |  2 +
 hypha/apply/funds/models/reviewer_role.py     |  6 +-
 hypha/apply/funds/models/submissions.py       |  2 +
 hypha/apply/funds/models/utils.py             |  2 +
 .../templates/funds/admin/parent_chooser.html |  2 +-
 hypha/apply/funds/tests/test_forms.py         |  2 +-
 hypha/apply/projects/admin_views.py           | 20 ------
 hypha/apply/projects/models/payment.py        |  6 ++
 hypha/apply/projects/models/project.py        |  8 ++-
 hypha/apply/projects/models/report.py         |  6 ++
 hypha/apply/projects/models/vendor.py         | 13 +++-
 hypha/apply/review/models.py                  |  3 +
 hypha/apply/stream_forms/models.py            |  1 +
 hypha/apply/users/models.py                   |  9 ++-
 .../templates/wagtailusers/users/edit.html    | 19 +++---
 .../templates/wagtailusers/users/index.html   | 41 +-----------
 .../templates/wagtailusers/users/list.html    | 54 ----------------
 .../templates/wagtailusers/users/results.html | 26 ++++----
 hypha/apply/users/wagtail_hooks.py            |  2 +-
 hypha/apply/utils/models.py                   |  4 +-
 hypha/cookieconsent/models.py                 |  4 +-
 ...01_wagtail_4_reference_index_dependency.py | 19 ++++++
 hypha/core/migrations/__init__.py             |  0
 .../wagtail/panels/inline_panel_readonly.html |  4 ++
 hypha/core/wagtail/admin/options.py           |  8 +--
 hypha/core/wagtail/admin/registry.py          |  4 +-
 .../migrations/0005_auto_20230214_0658.py     | 24 +++++++
 hypha/public/mailchimp/models.py              |  4 +-
 hypha/public/navigation/models.py             |  4 +-
 hypha/public/news/models.py                   |  4 +-
 hypha/public/partner/models.py                |  4 +-
 hypha/public/projects/models.py               |  2 +
 hypha/public/utils/models.py                  | 10 ++-
 requirements.txt                              |  4 +-
 45 files changed, 280 insertions(+), 271 deletions(-)
 create mode 100644 hypha/apply/funds/migrations/0110_auto_20230418_0644.py
 delete mode 100644 hypha/apply/users/templates/wagtailusers/users/list.html
 create mode 100644 hypha/core/migrations/0001_wagtail_4_reference_index_dependency.py
 create mode 100644 hypha/core/migrations/__init__.py
 create mode 100644 hypha/images/migrations/0005_auto_20230214_0658.py

diff --git a/.vscode/settings.json b/.vscode/settings.json
index d9063ce2b..f24ba4be3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -2,6 +2,10 @@
     "makefile.extensionOutputFolder": "./.vscode",
     "cSpell.words": [
         "Anymail",
-        "WAGTAILADMIN"
+        "coreutils",
+        "modelcluster",
+        "pagedown",
+        "WAGTAILADMIN",
+        "wagtailcore"
     ]
 }
diff --git a/hypha/apply/activity/models.py b/hypha/apply/activity/models.py
index a9c8563df..eadc6e510 100644
--- a/hypha/apply/activity/models.py
+++ b/hypha/apply/activity/models.py
@@ -114,6 +114,8 @@ class Activity(models.Model):
     comments = CommentManger.from_queryset(CommentQueryset)()
     actions = ActionManager.from_queryset(ActionQueryset)()
 
+    wagtail_reference_index_ignore = True
+
     class Meta:
         ordering = ['-timestamp']
         base_manager_name = 'objects'
@@ -149,6 +151,7 @@ class Activity(models.Model):
 
 class Event(models.Model):
     """Model to track when messages are triggered"""
+    wagtail_reference_index_ignore = True
 
     when = models.DateTimeField(auto_now_add=True)
     type = models.CharField(_("verb"), choices=MESSAGES.choices, max_length=50)
diff --git a/hypha/apply/categories/blocks.py b/hypha/apply/categories/blocks.py
index ab545f760..91da65662 100644
--- a/hypha/apply/categories/blocks.py
+++ b/hypha/apply/categories/blocks.py
@@ -1,33 +1,29 @@
 from django import forms
-from django.utils.functional import SimpleLazyObject, cached_property
+from django.utils.functional import cached_property
 from django.utils.translation import gettext_lazy as _
 from django_select2.forms import Select2MultipleWidget
-from wagtail.blocks import BooleanBlock, CharBlock, ChooserBlock, TextBlock
+from wagtail.blocks import BooleanBlock, CharBlock, ChoiceBlock, TextBlock
 from wagtail.coreutils import resolve_model_string
 
 from hypha.apply.stream_forms.blocks import OptionalFormFieldBlock
 
 
-class ModelChooserBlock(ChooserBlock):
-    widget = forms.Select
+class ModelChooserBlock(ChoiceBlock):
+    # Implement this block as it's referenced in the old migrations.
+    pass
 
-    def __init__(self, target_model, **kwargs):
-        self._target_model = target_model
-        super().__init__(**kwargs)
 
-    @cached_property
-    def target_model(self):
-        return resolve_model_string(self._target_model)
-
-    def to_python(self, value):
-        super_method = super().to_python
-        return SimpleLazyObject(lambda: super_method(value))
+def get_categories_as_choices():
+    Category = resolve_model_string("categories.Category")
+    return [(cat.id, cat.name) for cat in Category.objects.all()]
 
 
 class CategoryQuestionBlock(OptionalFormFieldBlock):
     class Meta:
         template = 'stream_forms/render_list_field.html'
 
+    category = ModelChooserBlock(required=True, choices=get_categories_as_choices)
+    multi = BooleanBlock(label=_('Multi select'), required=False)
     # Overwrite field label and help text so we can defer to the category
     # as required
     field_label = CharBlock(
@@ -40,14 +36,16 @@ class CategoryQuestionBlock(OptionalFormFieldBlock):
         required=False,
         help_text=_('Leave blank to use the default Category help text'),
     )
-    category = ModelChooserBlock('categories.Category')
-    multi = BooleanBlock(label=_('Multi select'), required=False)
+
+    @cached_property
+    def model_class(self):
+        return resolve_model_string("categories.Category")
+
+    def get_instance(self, id):
+        return self.model_class.objects.get(id=id)
 
     def get_field_class(self, struct_value):
-        if struct_value['multi']:
-            return forms.MultipleChoiceField
-        else:
-            return forms.ChoiceField
+        return forms.MultipleChoiceField if struct_value['multi'] else forms.ChoiceField
 
     def use_defaults_from_category(self, kwargs, category):
         category_fields = {'label': 'name', 'help_text': 'help_text'}
@@ -60,7 +58,7 @@ class CategoryQuestionBlock(OptionalFormFieldBlock):
 
     def get_field_kwargs(self, struct_value):
         kwargs = super().get_field_kwargs(struct_value)
-        category = struct_value['category']
+        category = self.get_instance(id=struct_value['category'])
         kwargs = self.use_defaults_from_category(kwargs, category)
         choices = category.options.values_list('id', 'value')
         kwargs.update({'choices': choices})
@@ -68,7 +66,7 @@ class CategoryQuestionBlock(OptionalFormFieldBlock):
 
     def get_widget(self, struct_value):
         if struct_value['multi']:
-            category = struct_value['category']
+            category = self.get_instance(id=struct_value['category'])
             category_size = category.options.count()
             # Pick widget according to number of options to maintain good usability.
             if category_size < 32:
@@ -83,7 +81,7 @@ class CategoryQuestionBlock(OptionalFormFieldBlock):
             return data
         if isinstance(data, str):
             data = [data]
-        category = value['category']
+        category = self.get_instance(id=value['category'])
         data = category.options.filter(id__in=data).values_list('value', flat=True)
         return data
 
@@ -93,8 +91,11 @@ class CategoryQuestionBlock(OptionalFormFieldBlock):
 
         for field in category_fields.keys():
             if not value.get(field):
-                value[field] = getattr(value['category'], category_fields[field])
-        return super(CategoryQuestionBlock, self).render(value, context)
+                category = value['category']
+                if isinstance(category, int):
+                    category = self.get_instance(id=category)
+                value[field] = getattr(category, category_fields[field])
+        return super().render(value, context)
 
     def get_searchable_content(self, value, data):
         return None
diff --git a/hypha/apply/determinations/models.py b/hypha/apply/determinations/models.py
index 117487cf3..f5ebe09ea 100644
--- a/hypha/apply/determinations/models.py
+++ b/hypha/apply/determinations/models.py
@@ -10,7 +10,7 @@ from wagtail.admin.panels import (
     ObjectList,
     TabbedInterface,
 )
-from wagtail.contrib.settings.models import BaseSetting, register_setting
+from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
 from wagtail.fields import RichTextField, StreamField
 
 from hypha.apply.funds.models.mixins import AccessFormData
@@ -43,6 +43,9 @@ class DeterminationQuerySet(models.QuerySet):
 
 
 class DeterminationFormFieldsMixin(models.Model):
+
+    wagtail_reference_index_ignore = True
+
     class Meta:
         abstract = True
 
@@ -184,7 +187,10 @@ class Determination(DeterminationFormFieldsMixin, AccessFormData, models.Model):
 
 
 @register_setting
-class DeterminationMessageSettings(BaseSetting):
+class DeterminationMessageSettings(BaseSiteSetting):
+
+    wagtail_reference_index_ignore = True
+
     class Meta:
         verbose_name = 'determination messages'
 
@@ -240,7 +246,7 @@ class DeterminationMessageSettings(BaseSetting):
 
 
 @register_setting
-class DeterminationFormSettings(BaseSetting):
+class DeterminationFormSettings(BaseSiteSetting):
     class Meta:
         verbose_name = 'determination form settings'
 
diff --git a/hypha/apply/funds/admin_views.py b/hypha/apply/funds/admin_views.py
index 8e6344c49..cd48115a7 100644
--- a/hypha/apply/funds/admin_views.py
+++ b/hypha/apply/funds/admin_views.py
@@ -101,15 +101,6 @@ class CopyApplicationFormViewClass(CreateView):
 
 class CreateApplicationFormView(CreateView):
 
-    def get_form(self):
-        """
-        Overriding this method to disable the single file block option from Application Form.
-        Set 0 as max_number of single file can be added to make single file block option unavailable or disable.
-        """
-        form = super(CreateApplicationFormView, self).get_form()
-        form.fields['form_fields'].block.meta.block_counts = {'file': {'min_num': 0, 'max_num': 0}}
-        return form
-
     def form_invalid(self, form):
         show_admin_form_error_messages(self.request, form)
         return self.render_to_response(self.get_context_data(form=form))
@@ -117,17 +108,6 @@ class CreateApplicationFormView(CreateView):
 
 class EditApplicationFormView(EditView):
 
-    def get_form(self):
-        """
-        Overriding this method to disable the single file block option from Application Form.
-        Calculating the number of Single file blocks that exist in the instance already.
-        And set that count as max_number of single file block can be added to make single file option disable.
-        """
-        form = super(EditApplicationFormView, self).get_form()
-        single_file_count = sum(1 for block in self.get_instance().form_fields.raw_data if block['type'] == 'file')
-        form.fields['form_fields'].block.meta.block_counts = {'file': {'min_num': 0, 'max_num': single_file_count}}
-        return form
-
     def form_invalid(self, form):
         show_admin_form_error_messages(self.request, form)
         return self.render_to_response(self.get_context_data(form=form))
diff --git a/hypha/apply/funds/edit_handlers.py b/hypha/apply/funds/edit_handlers.py
index 1988e3956..2439e3153 100644
--- a/hypha/apply/funds/edit_handlers.py
+++ b/hypha/apply/funds/edit_handlers.py
@@ -1,5 +1,4 @@
 from django.forms import Field, Widget
-from django.forms.utils import pretty_name
 from django.template.loader import render_to_string
 from django.urls import reverse
 from wagtail.admin.panels import FieldPanel, Panel
@@ -39,31 +38,26 @@ class DisplayField(Field):
 
 class ReadOnlyPanel(Panel):
     def __init__(self, attr: str, **kwargs):
-        self.attr = attr
         super().__init__(**kwargs)
-        self.heading = pretty_name(self.attr) if not self.heading else self.heading
+        self.attr = attr
 
     def clone_kwargs(self):
+        """Return a dictionary of keyword arguments that can be used to create
+        a clone of this panel definition.
         """
-        Return a dictionary of keyword arguments that can be used to create a clone of this panel definition.
-        """
-        return {
+        kwargs = super().clone_kwargs()
+        kwargs.update({
             "attr": self.attr,
-            "heading": self.heading,
-            "classname": self.classname,
-            "help_text": self.help_text,
-        }
+        })
+        return kwargs
+
 
     class BoundPanel(Panel.BoundPanel):
-        field_template_name = 'wagtailadmin/shared/field.html'
-        template_name = 'wagtailadmin/panels/single_field_panel.html'
+        template_name = 'wagtailadmin/panels/field_panel.html'
 
-        def render_as_object(self):
+        def render_html(self, parent_context):
             return render_to_string(self.template_name, self.context())
 
-        def render_as_field(self):
-            return render_to_string(self.field_template_name, self.context())
-
         def context(self):
             try:
                 value = getattr(self.instance, self.panel.attr)
@@ -79,7 +73,9 @@ class ReadOnlyPanel(Panel):
                 self.form.initial[self.panel.attr] = value
             else:
                 self.form.initial[self.panel.attr] = '-'
+
             self.bound_field = DisplayField().get_bound_field(self.form, self.panel.attr)
+
             return {
                 'self': self,
                 'field': self.bound_field,
diff --git a/hypha/apply/funds/forms.py b/hypha/apply/funds/forms.py
index 2068d65df..d3213f211 100644
--- a/hypha/apply/funds/forms.py
+++ b/hypha/apply/funds/forms.py
@@ -9,6 +9,7 @@ from django.conf import settings
 from django.utils.safestring import mark_safe
 from django.utils.text import slugify
 from django.utils.translation import gettext_lazy as _
+from wagtail.signal_handlers import disable_reference_index_auto_update
 
 from hypha.apply.categories.models import MetaTerm
 from hypha.apply.users.models import User
@@ -335,43 +336,44 @@ class UpdateReviewersForm(ApplicationSubmissionModelForm):
         return cleaned_data
 
     def save(self, *args, **kwargs):
-        instance = super().save(*args, **kwargs)
         """
         1. Update role reviewers
         2. Update non-role reviewers
             2a. Remove those not on form
             2b. Add in any new non-role reviewers selected
         """
+        with disable_reference_index_auto_update():
+            instance = super().save(*args, **kwargs)
+
+            # 1. Update role reviewers
+            assigned_roles = {
+                role: self.cleaned_data[field]
+                for field, role in self.role_fields.items()
+            }
+            for role, reviewer in assigned_roles.items():
+                if reviewer:
+                    AssignedReviewers.objects.update_role(role, reviewer, instance)
+                else:
+                    AssignedReviewers.objects.filter(role=role, submission=instance, review__isnull=True).delete()
+
+            # 2. Update non-role reviewers
+            # 2a. Remove those not on form
+            if self.can_alter_external_reviewers(self.instance, self.user):
+                reviewers = self.cleaned_data.get('reviewer_reviewers')
+                assigned_reviewers = instance.assigned.without_roles()
+                assigned_reviewers.never_tried_to_review().exclude(
+                    reviewer__in=reviewers
+                ).delete()
+
+                remaining_reviewers = assigned_reviewers.values_list('reviewer_id', flat=True)
+
+                # 2b. Add in any new non-role reviewers selected
+                AssignedReviewers.objects.bulk_create_reviewers(
+                    [reviewer for reviewer in reviewers if reviewer.id not in remaining_reviewers],
+                    instance,
+                )
 
-        # 1. Update role reviewers
-        assigned_roles = {
-            role: self.cleaned_data[field]
-            for field, role in self.role_fields.items()
-        }
-        for role, reviewer in assigned_roles.items():
-            if reviewer:
-                AssignedReviewers.objects.update_role(role, reviewer, instance)
-            else:
-                AssignedReviewers.objects.filter(role=role, submission=instance, review__isnull=True).delete()
-
-        # 2. Update non-role reviewers
-        # 2a. Remove those not on form
-        if self.can_alter_external_reviewers(self.instance, self.user):
-            reviewers = self.cleaned_data.get('reviewer_reviewers')
-            assigned_reviewers = instance.assigned.without_roles()
-            assigned_reviewers.never_tried_to_review().exclude(
-                reviewer__in=reviewers
-            ).delete()
-
-            remaining_reviewers = assigned_reviewers.values_list('reviewer_id', flat=True)
-
-            # 2b. Add in any new non-role reviewers selected
-            AssignedReviewers.objects.bulk_create_reviewers(
-                [reviewer for reviewer in reviewers if reviewer.id not in remaining_reviewers],
-                instance,
-            )
-
-        return instance
+            return instance
 
 
 class BatchUpdateReviewersForm(forms.Form):
diff --git a/hypha/apply/funds/migrations/0110_auto_20230418_0644.py b/hypha/apply/funds/migrations/0110_auto_20230418_0644.py
new file mode 100644
index 000000000..802fee467
--- /dev/null
+++ b/hypha/apply/funds/migrations/0110_auto_20230418_0644.py
@@ -0,0 +1,28 @@
+# Generated by Django 3.2.18 on 2023-04-18 06:44
+
+from django.db import migrations
+import hypha.apply.categories.blocks
+import hypha.apply.stream_forms.blocks
+import wagtail.blocks
+import wagtail.blocks.static_block
+import wagtail.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('funds', '0109_rename_section_text_field'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='applicationform',
+            name='form_fields',
+            field=wagtail.fields.StreamField([('text_markup', wagtail.blocks.RichTextBlock(group='Custom', label='Paragraph')), ('header_markup', wagtail.blocks.StructBlock([('heading_text', wagtail.blocks.CharBlock(form_classname='title', required=True)), ('size', wagtail.blocks.ChoiceBlock(choices=[('h2', 'H2'), ('h3', 'H3'), ('h4', 'H4')]))], group='Custom', label='Section header')), ('char', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('format', wagtail.blocks.ChoiceBlock(choices=[('email', 'Email'), ('url', 'URL')], label='Format', required=False)), ('default_value', wagtail.blocks.CharBlock(label='Default value', required=False))], group='Fields')), ('multi_inputs_char', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('format', wagtail.blocks.ChoiceBlock(choices=[('email', 'Email'), ('url', 'URL')], label='Format', required=False)), ('default_value', wagtail.blocks.CharBlock(label='Default value', required=False)), ('number_of_inputs', wagtail.blocks.IntegerBlock(default=2, label='Max number of inputs')), ('add_button_text', wagtail.blocks.CharBlock(default='Add new item', required=False))], group='Fields')), ('text', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('number', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.CharBlock(label='Default value', required=False))], group='Fields')), ('checkbox', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.BooleanBlock(required=False))], group='Fields')), ('radios', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.blocks.ListBlock(wagtail.blocks.CharBlock(label='Choice')))], group='Fields')), ('dropdown', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.blocks.ListBlock(wagtail.blocks.CharBlock(label='Choice')))], group='Fields')), ('checkboxes', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('checkboxes', wagtail.blocks.ListBlock(wagtail.blocks.CharBlock(label='Checkbox')))], group='Fields')), ('date', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.DateBlock(required=False))], group='Fields')), ('time', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.TimeBlock(required=False))], group='Fields')), ('datetime', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.DateTimeBlock(required=False))], group='Fields')), ('image', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('file', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('multi_file', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('group_toggle', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(default=True, label='Required', required=False)), ('choices', wagtail.blocks.ListBlock(wagtail.blocks.CharBlock(label='Choice'), help_text='Please create only two choices for toggle. First choice will revel the group and the second hide it. Additional choices will be ignored.'))], group='Custom')), ('group_toggle_end', hypha.apply.stream_forms.blocks.GroupToggleEndBlock(group='Custom')), ('rich_text', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('markdown_text', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('category', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(help_text='Leave blank to use the default Category label', label='Label', required=False)), ('help_text', wagtail.blocks.TextBlock(help_text='Leave blank to use the default Category help text', label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('category', wagtail.blocks.ChoiceBlock(choices=hypha.apply.categories.blocks.get_categories_as_choices)), ('multi', wagtail.blocks.BooleanBlock(label='Multi select', required=False))], group='Custom')), ('title', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(default='What is the title of your application?', label='Label')), ('help_text', wagtail.blocks.TextBlock(default='This project name can be changed if a full proposal is requested.', label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group=' Required')), ('email', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(default='What email address should we use to contact you?', label='Label')), ('help_text', wagtail.blocks.TextBlock(default='We will use this email address to communicate with you about your proposal.', label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group=' Required')), ('full_name', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(default='What is your name?', label='Label')), ('help_text', wagtail.blocks.TextBlock(default='We will use this name when we communicate with you about your proposal.', label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group=' Required')), ('value', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group='Custom')), ('address', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group='Custom')), ('duration', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('duration_type', wagtail.blocks.ChoiceBlock(choices=[('days', 'Days'), ('weeks', 'Weeks'), ('months', 'Months')], help_text='Duration type is used to display duration choices in Days, Weeks or Months in application forms. Be careful, changing the duration type in the active round can result in data inconsistency.')), ('info', wagtail.blocks.static_block.StaticBlock())], group='Custom'))], use_json_field=True),
+        ),
+        migrations.AlterField(
+            model_name='applicationsubmission',
+            name='form_fields',
+            field=wagtail.fields.StreamField([('text_markup', wagtail.blocks.RichTextBlock(group='Custom', label='Paragraph')), ('header_markup', wagtail.blocks.StructBlock([('heading_text', wagtail.blocks.CharBlock(form_classname='title', required=True)), ('size', wagtail.blocks.ChoiceBlock(choices=[('h2', 'H2'), ('h3', 'H3'), ('h4', 'H4')]))], group='Custom', label='Section header')), ('char', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('format', wagtail.blocks.ChoiceBlock(choices=[('email', 'Email'), ('url', 'URL')], label='Format', required=False)), ('default_value', wagtail.blocks.CharBlock(label='Default value', required=False))], group='Fields')), ('multi_inputs_char', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('format', wagtail.blocks.ChoiceBlock(choices=[('email', 'Email'), ('url', 'URL')], label='Format', required=False)), ('default_value', wagtail.blocks.CharBlock(label='Default value', required=False)), ('number_of_inputs', wagtail.blocks.IntegerBlock(default=2, label='Max number of inputs')), ('add_button_text', wagtail.blocks.CharBlock(default='Add new item', required=False))], group='Fields')), ('text', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('number', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.CharBlock(label='Default value', required=False))], group='Fields')), ('checkbox', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.BooleanBlock(required=False))], group='Fields')), ('radios', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.blocks.ListBlock(wagtail.blocks.CharBlock(label='Choice')))], group='Fields')), ('dropdown', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.blocks.ListBlock(wagtail.blocks.CharBlock(label='Choice')))], group='Fields')), ('checkboxes', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('checkboxes', wagtail.blocks.ListBlock(wagtail.blocks.CharBlock(label='Checkbox')))], group='Fields')), ('date', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.DateBlock(required=False))], group='Fields')), ('time', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.TimeBlock(required=False))], group='Fields')), ('datetime', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.DateTimeBlock(required=False))], group='Fields')), ('image', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('file', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('multi_file', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False))], group='Fields')), ('group_toggle', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(default=True, label='Required', required=False)), ('choices', wagtail.blocks.ListBlock(wagtail.blocks.CharBlock(label='Choice'), help_text='Please create only two choices for toggle. First choice will revel the group and the second hide it. Additional choices will be ignored.'))], group='Custom')), ('group_toggle_end', hypha.apply.stream_forms.blocks.GroupToggleEndBlock(group='Custom')), ('rich_text', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('markdown_text', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.blocks.TextBlock(label='Default value', required=False)), ('word_limit', wagtail.blocks.IntegerBlock(default=1000, label='Word limit'))], group='Fields')), ('category', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(help_text='Leave blank to use the default Category label', label='Label', required=False)), ('help_text', wagtail.blocks.TextBlock(help_text='Leave blank to use the default Category help text', label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('category', wagtail.blocks.ChoiceBlock(choices=hypha.apply.categories.blocks.get_categories_as_choices)), ('multi', wagtail.blocks.BooleanBlock(label='Multi select', required=False))], group='Custom')), ('title', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(default='What is the title of your application?', label='Label')), ('help_text', wagtail.blocks.TextBlock(default='This project name can be changed if a full proposal is requested.', label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group=' Required')), ('email', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(default='What email address should we use to contact you?', label='Label')), ('help_text', wagtail.blocks.TextBlock(default='We will use this email address to communicate with you about your proposal.', label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group=' Required')), ('full_name', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(default='What is your name?', label='Label')), ('help_text', wagtail.blocks.TextBlock(default='We will use this name when we communicate with you about your proposal.', label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group=' Required')), ('value', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group='Custom')), ('address', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('info', wagtail.blocks.static_block.StaticBlock())], group='Custom')), ('duration', wagtail.blocks.StructBlock([('field_label', wagtail.blocks.CharBlock(label='Label')), ('help_text', wagtail.blocks.TextBlock(label='Help text', required=False)), ('help_link', wagtail.blocks.URLBlock(label='Help link', required=False)), ('required', wagtail.blocks.BooleanBlock(label='Required', required=False)), ('duration_type', wagtail.blocks.ChoiceBlock(choices=[('days', 'Days'), ('weeks', 'Weeks'), ('months', 'Months')], help_text='Duration type is used to display duration choices in Days, Weeks or Months in application forms. Be careful, changing the duration type in the active round can result in data inconsistency.')), ('info', wagtail.blocks.static_block.StaticBlock())], group='Custom'))], use_json_field=True),
+        ),
+    ]
diff --git a/hypha/apply/funds/models/application_revisions.py b/hypha/apply/funds/models/application_revisions.py
index 79fa542d1..803e6f4fa 100644
--- a/hypha/apply/funds/models/application_revisions.py
+++ b/hypha/apply/funds/models/application_revisions.py
@@ -9,6 +9,8 @@ from .mixins import AccessFormData
 
 
 class ApplicationRevision(BaseStreamForm, AccessFormData, models.Model):
+    wagtail_reference_index_ignore = True
+
     submission = models.ForeignKey('funds.ApplicationSubmission', related_name='revisions', on_delete=models.CASCADE)
     form_data = models.JSONField(encoder=StreamFieldDataEncoder)
     timestamp = models.DateTimeField(auto_now=True)
diff --git a/hypha/apply/funds/models/applications.py b/hypha/apply/funds/models/applications.py
index 7a45bc7a0..00c4adf18 100644
--- a/hypha/apply/funds/models/applications.py
+++ b/hypha/apply/funds/models/applications.py
@@ -33,7 +33,7 @@ from wagtail.admin.panels import (
     ObjectList,
     TabbedInterface,
 )
-from wagtail.contrib.settings.models import BaseSetting, register_setting
+from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
 from wagtail.fields import RichTextField
 from wagtail.models import Page, PageManager
 from wagtail.query import PageQuerySet
@@ -132,7 +132,7 @@ class ApplicationBase(EmailForm, WorkflowStreamForm):  # type: ignore
         return self.open_round.serve(request)
 
     content_panels = WorkflowStreamForm.content_panels + [
-        FieldPanel('reviewers', widget=forms.SelectMultiple(attrs={'size': '16'})),
+        FieldPanel('reviewers', widget=forms.CheckboxSelectMultiple),
         FieldPanel('guide_link'),
         FieldPanel('description'),
         FieldPanel('image'),
@@ -204,7 +204,7 @@ class RoundBase(WorkflowStreamForm, SubmittableStreamForm):  # type: ignore
                 FieldPanel('end_date'),
             ]),
         ], heading=_('Dates')),
-        FieldPanel('reviewers', widget=forms.SelectMultiple(attrs={'size': '16'})),
+        FieldPanel('reviewers', widget=forms.CheckboxSelectMultiple),
         ReadOnlyPanel(
             'get_workflow_name_display',
             heading=_('Workflow'),
@@ -475,7 +475,7 @@ class LabBase(EmailForm, WorkflowStreamForm, SubmittableStreamForm):  # type: ig
 
     content_panels = WorkflowStreamForm.content_panels + [
         FieldPanel('lead'),
-        FieldPanel('reviewers', widget=forms.SelectMultiple(attrs={'size': '16'})),
+        FieldPanel('reviewers', widget=forms.CheckboxSelectMultiple),
         FieldPanel('guide_link'),
         FieldPanel('description'),
         FieldPanel('image'),
@@ -645,7 +645,10 @@ class RoundsAndLabs(Page):
 
 
 @register_setting
-class ApplicationSettings(BaseSetting):
+class ApplicationSettings(BaseSiteSetting):
+
+    wagtail_reference_index_ignore = True
+
     class Meta:
         verbose_name = 'application settings'
 
diff --git a/hypha/apply/funds/models/assigned_reviewers.py b/hypha/apply/funds/models/assigned_reviewers.py
index 1f616883a..21e9cfac0 100644
--- a/hypha/apply/funds/models/assigned_reviewers.py
+++ b/hypha/apply/funds/models/assigned_reviewers.py
@@ -144,6 +144,9 @@ class AssignedReviewersQuerySet(models.QuerySet):
 
 
 class AssignedReviewers(models.Model):
+
+    wagtail_reference_index_ignore = True
+
     reviewer = models.ForeignKey(
         settings.AUTH_USER_MODEL,
         on_delete=models.CASCADE,
diff --git a/hypha/apply/funds/models/forms.py b/hypha/apply/funds/models/forms.py
index 8b7a49bc7..9952020c2 100644
--- a/hypha/apply/funds/models/forms.py
+++ b/hypha/apply/funds/models/forms.py
@@ -9,6 +9,8 @@ from ..edit_handlers import FilteredFieldPanel
 
 
 class ApplicationForm(models.Model):
+    wagtail_reference_index_ignore = True
+
     name = models.CharField(max_length=255)
     form_fields = StreamField(ApplicationCustomFormFieldsBlock(), use_json_field=True)
 
diff --git a/hypha/apply/funds/models/reviewer_role.py b/hypha/apply/funds/models/reviewer_role.py
index d90e6ea5e..6ce08e306 100644
--- a/hypha/apply/funds/models/reviewer_role.py
+++ b/hypha/apply/funds/models/reviewer_role.py
@@ -1,7 +1,7 @@
 from django.db import models
 from django.utils.translation import gettext_lazy as _
 from wagtail.admin.panels import FieldPanel
-from wagtail.contrib.settings.models import BaseSetting, register_setting
+from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
 
 from hypha.apply.utils.image import generate_image_url
 
@@ -30,12 +30,14 @@ class ReviewerRole(models.Model):
     def icon_url(self, filter_spec):
         return generate_image_url(self.icon, filter_spec)
 
+    wagtail_reference_index_ignore = True
+
     def __str__(self):
         return self.name
 
 
 @register_setting
-class ReviewerSettings(BaseSetting):
+class ReviewerSettings(BaseSiteSetting):
     SUBMISSIONS = [
         ('all', 'All Submissions'),
         ('reviewed', 'Only reviewed Submissions'),
diff --git a/hypha/apply/funds/models/submissions.py b/hypha/apply/funds/models/submissions.py
index cbd5e7087..de6713b93 100644
--- a/hypha/apply/funds/models/submissions.py
+++ b/hypha/apply/funds/models/submissions.py
@@ -510,6 +510,8 @@ class ApplicationSubmission(
 
     objects = ApplicationSubmissionQueryset.as_manager()
 
+    wagtail_reference_index_ignore = True
+
     @property
     def is_draft(self):
         return self.status == DRAFT_STATE
diff --git a/hypha/apply/funds/models/utils.py b/hypha/apply/funds/models/utils.py
index 5298e51b1..62c441c84 100644
--- a/hypha/apply/funds/models/utils.py
+++ b/hypha/apply/funds/models/utils.py
@@ -92,6 +92,8 @@ class WorkflowStreamForm(WorkflowHelpers, AbstractStreamForm):  # type: ignore
     """
     Defines the common methods and fields for working with Workflows within Wagtail pages
     """
+    wagtail_reference_index_ignore = True
+
     class Meta:
         abstract = True
 
diff --git a/hypha/apply/funds/templates/funds/admin/parent_chooser.html b/hypha/apply/funds/templates/funds/admin/parent_chooser.html
index e8dbe2685..093a0239e 100644
--- a/hypha/apply/funds/templates/funds/admin/parent_chooser.html
+++ b/hypha/apply/funds/templates/funds/admin/parent_chooser.html
@@ -10,7 +10,7 @@
     }
     </style>
     {% block header %}
-        {% include "modeladmin/includes/header_with_breadcrumb.html" with title=view.get_page_title subtitle=view.get_page_subtitle icon=view.header_icon tabbed=True %}
+        {% include "wagtailadmin/shared/header_with_locale_selector.html" with title=view.get_page_title subtitle=view.get_page_subtitle icon=view.header_icon %}
     {% endblock %}
 
     <div class="nice-padding">
diff --git a/hypha/apply/funds/tests/test_forms.py b/hypha/apply/funds/tests/test_forms.py
index 21547bcf1..eb8615f64 100644
--- a/hypha/apply/funds/tests/test_forms.py
+++ b/hypha/apply/funds/tests/test_forms.py
@@ -92,7 +92,7 @@ class TestReviewerFormQueries(TestCase):
 
         # 1 - Submission
         # 1 - Select Review
-        # 2 - Cascase
+        # 2 - Cascade
         # 1 - Fetch data
         # 1 - Cache existing
         # 1 - auth group
diff --git a/hypha/apply/projects/admin_views.py b/hypha/apply/projects/admin_views.py
index 550174e05..16299278e 100644
--- a/hypha/apply/projects/admin_views.py
+++ b/hypha/apply/projects/admin_views.py
@@ -5,15 +5,6 @@ from hypha.apply.utils.blocks import show_admin_form_error_messages
 
 class CreateProjectApprovalFormView(CreateView):
 
-    def get_form(self):
-        """
-        Overriding this method to disable the single file block option from Project Approval Form.
-        Set 0 as max_number of single file can be added to make single file block option unavailable or disable.
-        """
-        form = super(CreateProjectApprovalFormView, self).get_form()
-        form.fields['form_fields'].block.meta.block_counts = {'file': {'min_num': 0, 'max_num': 0}}
-        return form
-
     def form_invalid(self, form):
         show_admin_form_error_messages(self.request, form)
         return self.render_to_response(self.get_context_data(form=form))
@@ -21,17 +12,6 @@ class CreateProjectApprovalFormView(CreateView):
 
 class EditProjectApprovalFormView(EditView):
 
-    def get_form(self):
-        """
-        Overriding this method to disable the single file block option from Project Approval Form.
-        Calculating the number of Single file blocks that exist in the instance already.
-        And set that count as max_number of single file block can be added to make single file option disable.
-        """
-        form = super(EditProjectApprovalFormView, self).get_form()
-        single_file_count = sum(1 for block in self.get_instance().form_fields.raw_data if block['type'] == 'file')
-        form.fields['form_fields'].block.meta.block_counts = {'file': {'min_num': 0, 'max_num': single_file_count}}
-        return form
-
     def form_invalid(self, form):
         show_admin_form_error_messages(self.request, form)
         return self.render_to_response(self.get_context_data(form=form))
diff --git a/hypha/apply/projects/models/payment.py b/hypha/apply/projects/models/payment.py
index bcafd0f4a..40ebfff2e 100644
--- a/hypha/apply/projects/models/payment.py
+++ b/hypha/apply/projects/models/payment.py
@@ -124,6 +124,8 @@ class InvoiceDeliverable(models.Model):
         default=0
     )
 
+    wagtail_reference_index_ignore = True
+
     def __str__(self):
         return self.deliverable.name
 
@@ -154,6 +156,8 @@ class Invoice(models.Model):
     )
     objects = InvoiceQueryset.as_manager()
 
+    wagtail_reference_index_ignore = True
+
     def __str__(self):
         return _('Invoice requested for {project}').format(project=self.project)
 
@@ -273,6 +277,8 @@ class Invoice(models.Model):
 
 
 class SupportingDocument(models.Model):
+    wagtail_reference_index_ignore = True
+
     document = models.FileField(
         upload_to="supporting_documents", storage=PrivateStorage()
     )
diff --git a/hypha/apply/projects/models/project.py b/hypha/apply/projects/models/project.py
index 812216dfb..cbb7867a9 100644
--- a/hypha/apply/projects/models/project.py
+++ b/hypha/apply/projects/models/project.py
@@ -21,9 +21,9 @@ from django.utils.translation import gettext_lazy as _
 from modelcluster.fields import ParentalKey, ParentalManyToManyField
 from modelcluster.models import ClusterableModel
 from wagtail.admin.panels import FieldPanel, InlinePanel, MultiFieldPanel
-from wagtail.contrib.settings.models import BaseSetting, register_setting
-from wagtail.core.models import Orderable
+from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
 from wagtail.fields import StreamField
+from wagtail.models import Orderable
 
 from addressfield.fields import ADDRESS_FIELDS_ORDER
 from hypha.apply.funds.models.mixins import AccessFormData
@@ -198,6 +198,8 @@ class Project(BaseStreamForm, AccessFormData, models.Model):
 
     objects = ProjectQuerySet.as_manager()
 
+    wagtail_reference_index_ignore = True
+
     def __str__(self):
         return self.title
 
@@ -472,7 +474,7 @@ class PAFReviewersRole(Orderable, ClusterableModel):
 
 
 @register_setting
-class ProjectSettings(BaseSetting, ClusterableModel):
+class ProjectSettings(BaseSiteSetting, ClusterableModel):
     contracting_gp_email = models.TextField("Contracting Group Email", null=True, blank=True)
     finance_gp_email = models.TextField("Finance Group Email", null=True, blank=True)
     staff_gp_email = models.TextField("Staff Group Email", null=True, blank=True)
diff --git a/hypha/apply/projects/models/report.py b/hypha/apply/projects/models/report.py
index 7fff2b9e6..2e92062f2 100644
--- a/hypha/apply/projects/models/report.py
+++ b/hypha/apply/projects/models/report.py
@@ -95,6 +95,8 @@ class Report(models.Model):
 
     objects = ReportQueryset.as_manager()
 
+    wagtail_reference_index_ignore = True
+
     class Meta:
         ordering = ('-end_date',)
 
@@ -161,11 +163,15 @@ class ReportVersion(models.Model):
         null=True,
     )
 
+    wagtail_reference_index_ignore = True
+
 
 class ReportPrivateFiles(models.Model):
     report = models.ForeignKey("ReportVersion", on_delete=models.CASCADE, related_name="files")
     document = models.FileField(upload_to=report_path, storage=PrivateStorage())
 
+    wagtail_reference_index_ignore = True
+
     @property
     def filename(self):
         return os.path.basename(self.document.name)
diff --git a/hypha/apply/projects/models/vendor.py b/hypha/apply/projects/models/vendor.py
index 315cf5d1d..20b2a50ce 100644
--- a/hypha/apply/projects/models/vendor.py
+++ b/hypha/apply/projects/models/vendor.py
@@ -3,7 +3,7 @@ from django.db import models
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from wagtail.admin.panels import FieldPanel, MultiFieldPanel
-from wagtail.contrib.settings.models import BaseSetting, register_setting
+from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
 from wagtail.fields import RichTextField
 
 from hypha.apply.utils.storage import PrivateStorage
@@ -36,6 +36,8 @@ class BankInformation(models.Model):
         verbose_name='National Identity Document Number'
     )
 
+    wagtail_reference_index_ignore = True
+
     def __str__(self):
         return self.account_holder_name
 
@@ -66,6 +68,8 @@ class Vendor(models.Model):
     # tracks updates to the Vendor fields via the Vendor Setup Form.
     user_has_updated_details = models.BooleanField(default=False)
 
+    wagtail_reference_index_ignore = True
+
     def __str__(self):
         return self.name
 
@@ -74,6 +78,7 @@ class Vendor(models.Model):
 
 
 class DueDiligenceDocument(models.Model):
+
     document = models.FileField(
         upload_to="due_diligence_documents", storage=PrivateStorage()
     )
@@ -83,12 +88,16 @@ class DueDiligenceDocument(models.Model):
         related_name='due_diligence_documents',
     )
 
+    wagtail_reference_index_ignore = True
+
     def __str__(self):
         return self.vendor.name + ' -> ' + self.document.name
 
 
 @register_setting
-class VendorFormSettings(BaseSetting):
+class VendorFormSettings(BaseSiteSetting):
+    wagtail_reference_index_ignore = True
+
     name_label = models.TextField(
         'label',
         default='1. What is the name of the person/organisation on the contract?'
diff --git a/hypha/apply/review/models.py b/hypha/apply/review/models.py
index 8585fd34a..1afbdaa2f 100644
--- a/hypha/apply/review/models.py
+++ b/hypha/apply/review/models.py
@@ -37,6 +37,9 @@ from .options import (
 
 
 class ReviewFormFieldsMixin(models.Model):
+
+    wagtail_reference_index_ignore = True
+
     class Meta:
         abstract = True
 
diff --git a/hypha/apply/stream_forms/models.py b/hypha/apply/stream_forms/models.py
index 11461e6dc..c8b85c5ed 100644
--- a/hypha/apply/stream_forms/models.py
+++ b/hypha/apply/stream_forms/models.py
@@ -23,6 +23,7 @@ from .forms import BlockFieldWrapper, PageStreamBaseForm
 
 class BaseStreamForm:
     submission_form_class = PageStreamBaseForm
+    wagtail_reference_index_ignore = True
 
     @classmethod
     def from_db(cls, db, field_names, values):
diff --git a/hypha/apply/users/models.py b/hypha/apply/users/models.py
index 53de8e2b1..4c44f89d5 100644
--- a/hypha/apply/users/models.py
+++ b/hypha/apply/users/models.py
@@ -9,7 +9,7 @@ from django.urls import reverse
 from django.utils.functional import cached_property
 from django.utils.translation import gettext_lazy as _
 from wagtail.admin.panels import FieldPanel, MultiFieldPanel
-from wagtail.contrib.settings.models import BaseSetting, register_setting
+from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
 from wagtail.fields import RichTextField
 
 from .groups import (
@@ -198,6 +198,8 @@ class User(AbstractUser):
 
     objects = UserManager()
 
+    wagtail_reference_index_ignore = True
+
     def __str__(self):
         return self.get_full_name() if self.get_full_name() else self.get_short_name()
 
@@ -290,7 +292,10 @@ class User(AbstractUser):
 
 
 @register_setting
-class UserSettings(BaseSetting):
+class UserSettings(BaseSiteSetting):
+
+    wagtail_reference_index_ignore = True
+
     class Meta:
         verbose_name = 'user settings'
 
diff --git a/hypha/apply/users/templates/wagtailusers/users/edit.html b/hypha/apply/users/templates/wagtailusers/users/edit.html
index ca1f54537..d1fa0563d 100644
--- a/hypha/apply/users/templates/wagtailusers/users/edit.html
+++ b/hypha/apply/users/templates/wagtailusers/users/edit.html
@@ -1,24 +1,23 @@
 <!-- Override the Wagtail's user edit template to add a custom 'Disable 2FA' button to account section-->
 {% extends "wagtailusers/users/edit.html" %}
-{% load i18n wagtailimages_tags users_tags %}
 {% load wagtailimages_tags %}
 {% load users_tags %}
 {% load i18n %}
 {% block content %}
 
     {% trans "Editing" as editing_str %}
-    {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=user.get_username merged=1 tabbed=1 icon="user" %}
+    {% include "wagtailadmin/shared/header.html" with title=editing_str subtitle=user.get_username merged=1 icon="user" %}
 
     <style>
         {# fix for checkbox alignment #}
         input[type=checkbox] {
-            vertical-align: text-bottom;
+            margin-bottom: .4rem;
         }
     </style>
 
     <div class="w-tabs" data-tabs>
         <div class="w-tabs__wrapper">
-            <div role="tablist" class="w-tabs__list nice-padding">
+            <div role="tablist" class="w-tabs__list">
                 {% trans "Account" as account_text %}
                 {% include 'wagtailadmin/shared/tabs/tab_nav_link.html' with tab_id='account' title=account_text %}
                 {% trans "Roles" as roles_text %}
@@ -27,7 +26,7 @@
         </div>
 
         <form action="{% url 'wagtailusers_users:edit' user.pk %}" method="POST" novalidate{% if form.is_multipart %} enctype="multipart/form-data"{% endif %}>
-            <div class="tab-content nice-padding">
+            <div class="tab-content">
                 {% csrf_token %}
 
                 <section
@@ -66,9 +65,9 @@
 
                         {% endblock fields %}
                         <li>
-                            <input type="submit" value="{% trans 'Save' %}" class="button" />
+                            <input type="submit" value="{% trans 'Save' %}" class="button"/>
                             {% if can_delete %}
-                                <a href="{% url 'wagtailusers_users:delete' user.pk %}" class="button button-secondary no">{% trans "Delete user" %}</a>
+                                <a href="{% url 'wagtailusers_users:delete' user.pk %}" class="button no">{% trans "Delete user" %}</a>
                             {% endif %}
                             <!-- Add a custom button to user account edit form -->
                             {% user_2fa_enabled user as is_2fa_enabled %}
@@ -94,9 +93,9 @@
 
                         {% include "wagtailadmin/shared/field_as_li.html" with field=form.groups %}
                         <li>
-                            <input type="submit" value="{% trans 'Save' %}" class="button" />
+                            <input type="submit" value="{% trans 'Save' %}" class="button"/>
                             {% if can_delete %}
-                                <a href="{% url 'wagtailusers_users:delete' user.pk %}" class="button button-secondary no">{% trans "Delete user" %}</a>
+                                <a href="{% url 'wagtailusers_users:delete' user.pk %}" class="button no">{% trans "Delete user" %}</a>
                             {% endif %}
                         </li>
                     </ul>
@@ -108,7 +107,6 @@
 
 {% block extra_css %}
     {{ block.super }}
-    {% include "wagtailadmin/pages/_editor_css.html" %}
     {{ form.media.css }}
 {% endblock %}
 {% block extra_js %}
@@ -116,4 +114,3 @@
     {% include "wagtailadmin/pages/_editor_js.html" %}
     {{ form.media.js }}
 {% endblock %}
-
diff --git a/hypha/apply/users/templates/wagtailusers/users/index.html b/hypha/apply/users/templates/wagtailusers/users/index.html
index 251f77009..4d5892bcc 100644
--- a/hypha/apply/users/templates/wagtailusers/users/index.html
+++ b/hypha/apply/users/templates/wagtailusers/users/index.html
@@ -1,41 +1,6 @@
-{% extends "wagtailadmin/base.html" %}
-{% load i18n static wagtailadmin_tags %}
-{% block titletag %}{% trans "Users" %}{% endblock %}
-{% block extra_js %}
-    {{ block.super }}
-    <script>
-        window.headerSearch = {
-            {% if group %}
-                url: "{% url 'wagtailusers_groups:users' group.id %}",
-            {% else %}
-                url: "{% url 'wagtailusers_users:index' %}",
-            {% endif %}
-            termInput: "#id_q",
-            targetOutput: "#user-results"
-        }
-    </script>
-    <script>
-        window.wagtailConfig.BULK_ACTION_ITEM_TYPE = 'USER';
-    </script>
-    <script defer src="{% versioned_static 'wagtailadmin/js/bulk-actions.js' %}"></script>
-{% endblock %}
+{% extends "wagtailusers/users/index.html" %}
+{% load  static %}
 
 {% block extra_css %}
-    <link rel="stylesheet" href="{% static 'css/apply/wagtail_users_list.css' %}" type="text/css" />
-{% endblock %}
-
-{% block content %}
-    {% trans "Users" as users_str %}
-    {% trans "Add a user" as add_a_user_str %}
-
-    {% url "wagtailusers_users:add" as add_link %}
-    {% include "wagtailadmin/shared/header.html" with subtitle=group.name title=users_str action_url=add_link action_text=add_a_user_str icon="user" search_url="wagtailusers_users:index" %}
-
-    <div class="nice-padding">
-        <div id="user-results" class="users">
-            {% include "wagtailusers/users/results.html" %}
-        </div>
-        {% trans "Select all users in listing" as select_all_text %}
-        {% include 'wagtailadmin/bulk_actions/footer.html' with select_all_obj_text=select_all_text app_label=app_label model_name=model_name objects=users %}
-    </div>
+    <link rel="stylesheet" href="{% static 'css/apply/wagtail_users_list.css' %}">
 {% endblock %}
diff --git a/hypha/apply/users/templates/wagtailusers/users/list.html b/hypha/apply/users/templates/wagtailusers/users/list.html
deleted file mode 100644
index c80d25ea8..000000000
--- a/hypha/apply/users/templates/wagtailusers/users/list.html
+++ /dev/null
@@ -1,54 +0,0 @@
-{% load i18n l10n wagtailusers_tags wagtailadmin_tags %}
-<table class="listing">
-    <thead>
-        <tr>
-            {% include 'wagtailadmin/bulk_actions/select_all_checkbox_cell.html' %}
-            <th class="name">
-                {% trans "Name" %}
-                {% if ordering == "name" %}
-                    <a href="{% url 'wagtailusers_users:index' %}" class="icon icon-arrow-down-after teal"></a>
-                {% else %}
-                    <a href="{% url 'wagtailusers_users:index' %}?ordering=name" class="icon icon-arrow-down-after"></a>
-                {% endif %}
-            </th>
-            <th class="username">
-                {% trans "Username" %}
-                {% if ordering == "username" %}
-                    <a href="{% url 'wagtailusers_users:index' %}" class="icon icon-arrow-down-after teal"></a>
-                {% else %}
-                    <a href="{% url 'wagtailusers_users:index' %}?ordering=username" class="icon icon-arrow-down-after"></a>
-                {% endif %}
-            </th>
-            <th class="level">{% trans "Role" %}</th>
-            <th class="status">
-                {% trans "Status" %}
-                {% if ordering == "status" %}
-                    <a href="{% url 'wagtailusers_users:index' %}" class="icon icon-arrow-down-after teal"></a>
-                {% else %}
-                    <a href="{% url 'wagtailusers_users:index' %}?ordering=status" class="icon icon-arrow-down-after"></a>
-                {% endif %}
-            </th>
-            <th class="last-login">{% trans "Last Login" %}</th>
-        </tr>
-    </thead>
-    <tbody>
-        {% for user in users %}
-            <tr>
-                {% include "wagtailadmin/bulk_actions/listing_checkbox_cell.html" with obj_type="user" obj=user aria_labelledby_prefix="user_" aria_labelledby=user.pk|unlocalize aria_labelledby_suffix="_title" %}
-                <td id="user_{{ user.pk|unlocalize }}_title" class="title" valign="top">
-                    <h2 class="title-wrapper">
-                        <span class="avatar small"><img src="{% avatar_url user size=25 %}" alt="" /></span>
-                        <a href="{% url 'wagtailusers_users:edit' user.pk %}">{{ user.get_full_name|default:user.get_username }}</a>
-                    </h2>
-                    <ul class="actions">
-                        {% user_listing_buttons user %}
-                    </ul>
-                </td>
-                <td class="username" valign="top">{{ user.get_username }}</td>
-                <td class="level" valign="top">{{ user.roles|join:', ' }}{% if user.is_superuser %} ({% trans "Admin" %}){% endif %}</td>
-                <td class="status" valign="top"><div class="status-tag {% if user.is_active %}primary{% endif %}">{% if user.is_active %}{% trans "Active" %}{% else %}{% trans "Inactive" %}{% endif %}</div></td>
-                <td {% if user.last_login %} class="human-readable-date" title="{{ user.last_login|date:"d M Y H:i" }}"{% endif %}>{% if user.last_login %}{% blocktrans with time_period=user.last_login|timesince %}{{ time_period }} ago{% endblocktrans %}{% endif %}</td>
-            </tr>
-        {% endfor %}
-    </tbody>
-</table>
diff --git a/hypha/apply/users/templates/wagtailusers/users/results.html b/hypha/apply/users/templates/wagtailusers/users/results.html
index d3530432f..067e8481c 100644
--- a/hypha/apply/users/templates/wagtailusers/users/results.html
+++ b/hypha/apply/users/templates/wagtailusers/users/results.html
@@ -2,26 +2,26 @@
 <div class="users-list{% if filters %} users-list--has-filters{% endif %}">
     <div class="users-list__results">
         {% if users %}
-            <h2 role="alert">
-            {% if user_count %}
-                {% blocktrans trimmed count counter=user_count %}
-                    There is {{ counter }} user
-                {% plural %}
-                    There are {{ counter }} users
-                {% endblocktrans %}
-            {% endif %}
-            </h2>
-
             {% if is_searching %}
+                <h2 role="alert">
+                    {% blocktrans trimmed count counter=users|length %}
+                        There is {{ counter }} match
+                    {% plural %}
+                        There are {{ counter }} matches
+                    {% endblocktrans %}
+                </h2>
+
                 {% search_other %}
             {% endif %}
+
             {% include "wagtailusers/users/list.html" %}
 
-            {# call pagination_nav with no linkurl, to generate general-purpose links like <div href="?p=2"/> #}
-            {% include "wagtailadmin/shared/pagination_nav.html" with items=users %}
+            {# call pagination_nav with no linkurl, to generate general-purpose links like <a href="?p=2"> #}
+            {% include "wagtailadmin/shared/pagination_nav.html" with items=page_obj %}
         {% else %}
-            <h2 role="alert">{% blocktrans trimmed %}Sorry, no users match "<em>{{ query_string }}</em>"{% endblocktrans %}</h2>
             {% if is_searching %}
+                <h2 role="alert">{% blocktrans trimmed %}Sorry, no users match "<em>{{ query_string }}</em>"{% endblocktrans %}</h2>
+
                 {% search_other %}
             {% else %}
                 {% url 'wagtailusers_users:add' as wagtailusers_add_url %}
diff --git a/hypha/apply/users/wagtail_hooks.py b/hypha/apply/users/wagtail_hooks.py
index bf08c8efe..eb3e6fe2c 100644
--- a/hypha/apply/users/wagtail_hooks.py
+++ b/hypha/apply/users/wagtail_hooks.py
@@ -1,6 +1,6 @@
 from django.urls import re_path
 from wagtail import hooks
-from wagtail.core.models import Site
+from wagtail.models import Site
 
 from hypha.apply.activity.messaging import MESSAGES, messenger
 
diff --git a/hypha/apply/utils/models.py b/hypha/apply/utils/models.py
index 6031c5e6d..cdd22890e 100644
--- a/hypha/apply/utils/models.py
+++ b/hypha/apply/utils/models.py
@@ -1,11 +1,11 @@
 from django.db import models
 from django.utils.translation import gettext_lazy as _
 from wagtail.admin.panels import FieldPanel
-from wagtail.contrib.settings.models import BaseSetting, register_setting
+from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
 
 
 @register_setting
-class PDFPageSettings(BaseSetting):
+class PDFPageSettings(BaseSiteSetting):
     A4 = 'A4'
     LEGAL = 'legal'
     LETTER = 'letter'
diff --git a/hypha/cookieconsent/models.py b/hypha/cookieconsent/models.py
index 56334b8ce..789d70c67 100644
--- a/hypha/cookieconsent/models.py
+++ b/hypha/cookieconsent/models.py
@@ -1,13 +1,13 @@
 from django.db import models
 from wagtail.admin.panels import FieldPanel, MultiFieldPanel
-from wagtail.contrib.settings.models import BaseSetting
+from wagtail.contrib.settings.models import BaseSiteSetting
 from wagtail.fields import RichTextField
 
 from hypha.core.wagtail.admin.registry import register_public_site_setting
 
 
 @register_public_site_setting
-class CookieConsentSettings(BaseSetting):
+class CookieConsentSettings(BaseSiteSetting):
     class Meta:
         verbose_name = 'Cookie consent settings'
 
diff --git a/hypha/core/migrations/0001_wagtail_4_reference_index_dependency.py b/hypha/core/migrations/0001_wagtail_4_reference_index_dependency.py
new file mode 100644
index 000000000..247fb641b
--- /dev/null
+++ b/hypha/core/migrations/0001_wagtail_4_reference_index_dependency.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.2.16 on 2022-12-12 08:37
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+    """This migration is added to ensure all the migrations from wagtail is
+    picked up and ran during the testing.
+
+    The migrations from wagtail are picked up while running the "python manage.py migrate"
+    but it somehow fails while the database schema is generated while running the django tests.
+    """
+
+    dependencies = [
+        ("wagtailcore", "0078_referenceindex"),
+    ]
+
+    operations = [
+    ]
diff --git a/hypha/core/migrations/__init__.py b/hypha/core/migrations/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/hypha/core/templates/core/wagtail/panels/inline_panel_readonly.html b/hypha/core/templates/core/wagtail/panels/inline_panel_readonly.html
index 0fc02dad1..ed10e8224 100644
--- a/hypha/core/templates/core/wagtail/panels/inline_panel_readonly.html
+++ b/hypha/core/templates/core/wagtail/panels/inline_panel_readonly.html
@@ -2,6 +2,10 @@
 
 {{ self.formset.management_form }}
 
+{% if self.help_text %}
+    {% help_block status="info" %}{{ self.help_text }}{% endhelp_block %}
+{% endif %}
+
 <ul class="multiple" id="id_{{ self.formset.prefix }}-FORMS">
     {% if self.formset.non_form_errors %}
         <li class="error-message">
diff --git a/hypha/core/wagtail/admin/options.py b/hypha/core/wagtail/admin/options.py
index 2f5789de4..5ee9bade8 100644
--- a/hypha/core/wagtail/admin/options.py
+++ b/hypha/core/wagtail/admin/options.py
@@ -2,7 +2,7 @@ from django.contrib.auth.models import Permission
 from django.core.exceptions import ImproperlyConfigured
 from wagtail.contrib.modeladmin.helpers import PagePermissionHelper, PermissionHelper
 from wagtail.contrib.modeladmin.options import WagtailRegisterable
-from wagtail.contrib.settings.models import BaseSetting
+from wagtail.contrib.settings.models import BaseSiteSetting
 from wagtail.contrib.settings.registry import SettingMenuItem
 from wagtail.models import Page
 
@@ -13,7 +13,7 @@ class SettingModelAdmin(WagtailRegisterable):
     adding a SettingModelAdmin class just like ModelAdmin to the ModelGroupAdmin
     as an item.
 
-    The BaseSetting still needs to be registered with `@register_setting` decorator
+    The BaseSiteSetting still needs to be registered with `@register_setting` decorator
     and will show up in the setting menu.
     """
 
@@ -25,10 +25,10 @@ class SettingModelAdmin(WagtailRegisterable):
         """
         Don't allow initialization unless self.model is set to a valid model
         """
-        if not self.model or not issubclass(self.model, BaseSetting):
+        if not self.model or not issubclass(self.model, BaseSiteSetting):
             raise ImproperlyConfigured(
                 "The model attribute on your '%s' class must be set, and "
-                "must be inherit BaseSetting class." % self.__class__.__name__
+                "must be inherit BaseSiteSetting class." % self.__class__.__name__
             )
         self.parent = parent
 
diff --git a/hypha/core/wagtail/admin/registry.py b/hypha/core/wagtail/admin/registry.py
index 9f0644b8e..7549a7537 100644
--- a/hypha/core/wagtail/admin/registry.py
+++ b/hypha/core/wagtail/admin/registry.py
@@ -2,7 +2,7 @@ from django.contrib.auth.models import Permission
 from wagtail import hooks
 from wagtail.admin.admin_url_finder import register_admin_url_finder
 from wagtail.contrib.settings.registry import Registry as WagtailSettingsRegistry
-from wagtail.contrib.settings.registry import SettingMenuItem, SettingsAdminURLFinder
+from wagtail.contrib.settings.registry import SettingMenuItem, SiteSettingAdminURLFinder
 from wagtail.contrib.settings.registry import registry as wagtail_settings_registry
 from wagtail.permission_policies import ModelPermissionPolicy
 
@@ -34,7 +34,7 @@ class PublicSiteSettingsRegistry(WagtailSettingsRegistry):
         permission_policy = ModelPermissionPolicy(model)
         finder_class = type(
             "_SettingsAdminURLFinder",
-            (SettingsAdminURLFinder,),
+            (SiteSettingAdminURLFinder,),
             {"model": model, "permission_policy": permission_policy},
         )
         register_admin_url_finder(model, finder_class)
diff --git a/hypha/images/migrations/0005_auto_20230214_0658.py b/hypha/images/migrations/0005_auto_20230214_0658.py
new file mode 100644
index 000000000..74c49eba3
--- /dev/null
+++ b/hypha/images/migrations/0005_auto_20230214_0658.py
@@ -0,0 +1,24 @@
+# Generated by Django 3.2.17 on 2023-02-14 06:58
+
+from django.db import migrations
+import wagtail.images.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('images', '0004_alter_customimage_file_hash'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='customimage',
+            name='file',
+            field=wagtail.images.models.WagtailImageField(height_field='height', upload_to=wagtail.images.models.get_upload_to, verbose_name='file', width_field='width'),
+        ),
+        migrations.AlterField(
+            model_name='rendition',
+            name='file',
+            field=wagtail.images.models.WagtailImageField(height_field='height', upload_to=wagtail.images.models.get_rendition_upload_to, width_field='width'),
+        ),
+    ]
diff --git a/hypha/public/mailchimp/models.py b/hypha/public/mailchimp/models.py
index 8022d98a3..68e66d828 100644
--- a/hypha/public/mailchimp/models.py
+++ b/hypha/public/mailchimp/models.py
@@ -1,13 +1,13 @@
 from django.db import models
 from django.utils.translation import gettext_lazy as _
 from wagtail.admin.panels import FieldPanel
-from wagtail.contrib.settings.models import BaseSetting
+from wagtail.contrib.settings.models import BaseSiteSetting
 
 from hypha.core.wagtail.admin import register_public_site_setting
 
 
 @register_public_site_setting
-class NewsletterSettings(BaseSetting):
+class NewsletterSettings(BaseSiteSetting):
     class Meta:
         verbose_name = 'newsletter settings'
 
diff --git a/hypha/public/navigation/models.py b/hypha/public/navigation/models.py
index 8b70e0764..d49fa4938 100644
--- a/hypha/public/navigation/models.py
+++ b/hypha/public/navigation/models.py
@@ -2,7 +2,7 @@ from django.utils.translation import gettext_lazy as _
 from modelcluster.models import ClusterableModel
 from wagtail import blocks
 from wagtail.admin.panels import FieldPanel
-from wagtail.contrib.settings.models import BaseSetting
+from wagtail.contrib.settings.models import BaseSiteSetting
 from wagtail.fields import StreamField
 
 from hypha.core.wagtail.admin import register_public_site_setting
@@ -17,7 +17,7 @@ class LinkBlock(blocks.StructBlock):
 
 
 @register_public_site_setting(icon='', classnames='icon icon-list-ul')
-class NavigationSettings(BaseSetting, ClusterableModel):
+class NavigationSettings(BaseSiteSetting, ClusterableModel):
     primary_navigation = StreamField(
         [('link', LinkBlock()), ],
         blank=True,
diff --git a/hypha/public/news/models.py b/hypha/public/news/models.py
index a6328a09d..c898efd30 100644
--- a/hypha/public/news/models.py
+++ b/hypha/public/news/models.py
@@ -6,7 +6,7 @@ from django.utils.translation import gettext_lazy as _
 from modelcluster.fields import ParentalKey
 from pagedown.widgets import PagedownWidget
 from wagtail.admin.panels import FieldPanel, InlinePanel, PageChooserPanel
-from wagtail.contrib.settings.models import BaseSetting
+from wagtail.contrib.settings.models import BaseSiteSetting
 from wagtail.fields import StreamField
 from wagtail.models import Orderable
 from wagtail.search import index
@@ -168,7 +168,7 @@ class NewsIndex(BasePage):
 
 
 @register_public_site_setting
-class NewsFeedSettings(BaseSetting):
+class NewsFeedSettings(BaseSiteSetting):
     news_title = models.CharField(max_length=255, help_text=_('The title of the main news feed.'))
     news_description = models.CharField(max_length=255, help_text=_('The description of the main news feed.'))
 
diff --git a/hypha/public/partner/models.py b/hypha/public/partner/models.py
index ae84d1776..d956dd3cb 100644
--- a/hypha/public/partner/models.py
+++ b/hypha/public/partner/models.py
@@ -10,7 +10,7 @@ from django.utils.translation import gettext_lazy as _
 from pagedown.widgets import PagedownWidget
 from wagtail.admin.forms import WagtailAdminModelForm
 from wagtail.admin.panels import FieldPanel
-from wagtail.contrib.settings.models import BaseSetting
+from wagtail.contrib.settings.models import BaseSiteSetting
 from wagtail.fields import RichTextField
 from wagtail.models import Page
 from wagtail.search import index
@@ -115,7 +115,7 @@ def max_value_current_year(value):
 
 
 @register_public_site_setting
-class InvestmentCategorySettings(BaseSetting):
+class InvestmentCategorySettings(BaseSiteSetting):
     class Meta:
         verbose_name = _('Investment Category Settings')
 
diff --git a/hypha/public/projects/models.py b/hypha/public/projects/models.py
index 3f18d827e..ca772ed50 100644
--- a/hypha/public/projects/models.py
+++ b/hypha/public/projects/models.py
@@ -114,6 +114,8 @@ class ProjectPage(FundingMixin, BasePage):
 
     categories = models.TextField(default='{}', blank=True)
 
+    wagtail_reference_index_ignore = True
+
     search_fields = BasePage.search_fields + [
         index.SearchField('introduction'),
         index.SearchField('body'),
diff --git a/hypha/public/utils/models.py b/hypha/public/utils/models.py
index 118a89a81..218a664de 100644
--- a/hypha/public/utils/models.py
+++ b/hypha/public/utils/models.py
@@ -11,7 +11,7 @@ from wagtail.admin.panels import (
     MultiFieldPanel,
     PageChooserPanel,
 )
-from wagtail.contrib.settings.models import BaseSetting
+from wagtail.contrib.settings.models import BaseSiteSetting
 from wagtail.fields import RichTextField, StreamField
 from wagtail.models import Orderable, Page
 from wagtail.snippets.models import register_snippet
@@ -199,7 +199,7 @@ class CallToActionSnippet(models.Model):
 
 
 @register_public_site_setting
-class SocialMediaSettings(BaseSetting):
+class SocialMediaSettings(BaseSiteSetting):
     twitter_handle = models.CharField(
         max_length=255,
         blank=True,
@@ -224,7 +224,10 @@ class SocialMediaSettings(BaseSetting):
 
 
 @register_public_site_setting
-class SystemMessagesSettings(BaseSetting):
+class SystemMessagesSettings(BaseSiteSetting):
+
+    wagtail_reference_index_ignore = True
+
     class Meta:
         verbose_name = 'System settings'
 
@@ -284,6 +287,7 @@ class SystemMessagesSettings(BaseSetting):
 
 @method_decorator(cache_page, name='serve')
 class BasePage(WagtailCacheMixin, SocialFields, ListingFields, Page):
+    wagtail_reference_index_ignore = True
     show_in_menus_default = True
 
     header_image = models.ForeignKey(
diff --git a/requirements.txt b/requirements.txt
index 8b3d639ff..0a16aff26 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -50,9 +50,9 @@ reportlab==3.6.12
 social_auth_app_django==5.0.0
 tablib==3.3.0
 tomd==0.1.3
-wagtail-cache==2.1.0
+wagtail-cache==2.2.0
 wagtail-purge==0.2
-wagtail==3.0.1
+wagtail==4.2.2
 whitenoise==5.3.0
 xhtml2pdf==0.2.8
 xmltodict==0.13.0
-- 
GitLab