Add fallback on full-word search to generic model IndexView

stable/5.1.x
Matt Westcott 2023-09-11 17:28:06 +01:00
rodzic 7dceae5feb
commit 708e69f272
2 zmienionych plików z 56 dodań i 3 usunięć

Wyświetl plik

@ -1,3 +1,5 @@
import warnings
from django import VERSION as DJANGO_VERSION
from django.contrib.admin.utils import label_for_field, quote, unquote
from django.contrib.contenttypes.models import ContentType
@ -254,9 +256,21 @@ class IndexView(LocaleMixin, PermissionCheckedMixin, BaseListingView):
if class_is_indexed(queryset.model) and self.search_backend_name:
search_backend = get_search_backend(self.search_backend_name)
return search_backend.autocomplete(
self.search_query, queryset, fields=self.search_fields
)
if queryset.model.get_autocomplete_search_fields():
return search_backend.autocomplete(
self.search_query, queryset, fields=self.search_fields
)
else:
# fall back on non-autocompleting search
warnings.warn(
f"{queryset.model} is defined as Indexable but does not specify "
"any AutocompleteFields. Searches within the admin will only "
"respond to complete words.",
category=RuntimeWarning,
)
return search_backend.search(
self.search_query, queryset, fields=self.search_fields
)
filters = {
field + "__icontains": self.search_query

Wyświetl plik

@ -509,6 +509,45 @@ class TestSnippetListViewWithSearchableSnippet(WagtailTestUtils, TransactionTest
self.assertIn(self.snippet_c, items)
class TestSnippetListViewWithNonAutocompleteSearchableSnippet(
WagtailTestUtils, TransactionTestCase
):
"""
Test that searchable snippets with no AutocompleteFields defined can still be searched using
full words
"""
def setUp(self):
self.login()
# Create some instances of the searchable snippet for testing
self.snippet_a = NonAutocompleteSearchableSnippet.objects.create(text="Hello")
self.snippet_b = NonAutocompleteSearchableSnippet.objects.create(text="World")
self.snippet_c = NonAutocompleteSearchableSnippet.objects.create(
text="Hello World"
)
def get(self, params={}):
return self.client.get(
reverse(
"wagtailsnippets_snippetstests_nonautocompletesearchablesnippet:list"
),
params,
)
def test_search_hello(self):
with self.assertWarnsRegex(
RuntimeWarning, "does not specify any AutocompleteFields"
):
response = self.get({"q": "Hello"})
# Just snippets with "Hello" should be in items
items = list(response.context["page_obj"].object_list)
self.assertIn(self.snippet_a, items)
self.assertNotIn(self.snippet_b, items)
self.assertIn(self.snippet_c, items)
class TestSnippetCreateView(WagtailTestUtils, TestCase):
def setUp(self):
self.user = self.login()