diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 4f4e41b056..0d4dbaee37 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -29,6 +29,7 @@ Changelog
* Fix: Ensure that disabled buttons have a consistent presentation on hover to indicate no interaction is available (Paarth Agarwal)
* Fix: Update the 'Locked pages' report menu title so that it is consistent with other pages reports and its own title on viewing (Nicholas Johnson)
* Fix: Support `formfield_callback` handling on `ModelForm.Meta` for future Django 4.2 release (Matt Westcott)
+ * Fix: Ensure that `ModelAdmin` correctly supports filters in combination with subsequent searches without clearing the applied filters (Stefan Hammer)
4.0.2 (xx.xx.xxxx) - IN DEVELOPMENT
diff --git a/docs/releases/4.1.md b/docs/releases/4.1.md
index 4552de0567..67314160de 100644
--- a/docs/releases/4.1.md
+++ b/docs/releases/4.1.md
@@ -41,6 +41,7 @@ Wagtail 4.1 is designated a Long Term Support (LTS) release. Long Term Support r
* Ensure that disabled buttons have a consistent presentation on hover to indicate no interaction is available (Paarth Agarwal)
* Update the 'Locked pages' report menu title so that it is consistent with other pages reports and its own title on viewing (Nicholas Johnson)
* Support `formfield_callback` handling on `ModelForm.Meta` for future Django 4.2 release (Matt Westcott)
+ * Ensure that `ModelAdmin` correctly supports filters in combination with subsequent searches without clearing the applied filters (Stefan Hammer)
## Upgrade considerations
diff --git a/wagtail/contrib/modeladmin/templates/modeladmin/includes/search_form.html b/wagtail/contrib/modeladmin/templates/modeladmin/includes/search_form.html
index d2a516eb4e..6c3d7a5a0b 100644
--- a/wagtail/contrib/modeladmin/templates/modeladmin/includes/search_form.html
+++ b/wagtail/contrib/modeladmin/templates/modeladmin/includes/search_form.html
@@ -6,5 +6,9 @@
{% endfield %}
+ {# Keep all parameters from the query string (e.g. filter state). #}
+ {% for name, value in view.params.items %}
+ {% if name != search_var %}{% endif %}
+ {% endfor %}
{% endif %}
diff --git a/wagtail/contrib/modeladmin/tests/test_simple_modeladmin.py b/wagtail/contrib/modeladmin/tests/test_simple_modeladmin.py
index 60b748b902..6c23de93b3 100644
--- a/wagtail/contrib/modeladmin/tests/test_simple_modeladmin.py
+++ b/wagtail/contrib/modeladmin/tests/test_simple_modeladmin.py
@@ -156,6 +156,13 @@ class TestBookIndexView(TestCase, WagtailTestUtils):
response, '2 out of 4', html=True
)
+ # The search form should retain the filter
+ self.assertContains(
+ response,
+ '',
+ html=True,
+ )
+
for book in response.context["object_list"]:
self.assertEqual(book.author_id, 1)