kopia lustrzana https://github.com/wagtail/wagtail
Support searching `none()` querysets (#12873)
rodzic
e01aaed00c
commit
88abe5872c
docs/releases
wagtail/search
backends
tests
|
@ -22,7 +22,7 @@ Changelog
|
|||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix: Prevent error when filtering by locale and searching with Elasticsearch (Sage Abdullah)
|
||||
|
||||
* Fix: Support searching `none()` querysets (Matt Westcott)
|
||||
|
||||
6.4 (03.02.2025)
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -14,3 +14,4 @@ depth: 1
|
|||
### Bug fixes
|
||||
|
||||
* Prevent error when filtering by locale and searching with Elasticsearch (Sage Abdullah)
|
||||
* Support searching `none()` querysets (Matt Westcott)
|
||||
|
|
|
@ -5,7 +5,7 @@ from django.db.models.functions.datetime import Extract as ExtractDate
|
|||
from django.db.models.functions.datetime import ExtractYear
|
||||
from django.db.models.lookups import Lookup
|
||||
from django.db.models.query import QuerySet
|
||||
from django.db.models.sql.where import SubqueryConstraint, WhereNode
|
||||
from django.db.models.sql.where import NothingNode, SubqueryConstraint, WhereNode
|
||||
|
||||
from wagtail.search.index import class_is_indexed, get_indexed_models
|
||||
from wagtail.search.query import MATCH_ALL, PlainText
|
||||
|
@ -69,6 +69,9 @@ class BaseSearchQueryCompiler:
|
|||
def _process_lookup(self, field, lookup, value):
|
||||
raise NotImplementedError
|
||||
|
||||
def _process_match_none(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def _connect_filters(self, filters, connector, negated):
|
||||
raise NotImplementedError
|
||||
|
||||
|
@ -179,6 +182,9 @@ class BaseSearchQueryCompiler:
|
|||
field_attname, lookup, value, check_only=check_only
|
||||
)
|
||||
|
||||
elif isinstance(where_node, NothingNode):
|
||||
return self._process_match_none()
|
||||
|
||||
elif isinstance(where_node, SubqueryConstraint):
|
||||
raise FilterError(
|
||||
"Could not apply filter on search results: Subqueries are not allowed."
|
||||
|
|
|
@ -56,6 +56,9 @@ class DatabaseSearchQueryCompiler(BaseSearchQueryCompiler):
|
|||
**{field.get_attname(self.queryset.model) + "__" + lookup: value}
|
||||
)
|
||||
|
||||
def _process_match_none(self):
|
||||
return models.Q(pk__in=[])
|
||||
|
||||
def _connect_filters(self, filters, connector, negated):
|
||||
if connector == "AND":
|
||||
q = models.Q(*filters)
|
||||
|
|
|
@ -522,6 +522,9 @@ class MySQLSearchQueryCompiler(BaseSearchQueryCompiler):
|
|||
lhs = field.get_attname(self.queryset.model) + "__" + lookup
|
||||
return Q(**{lhs: value})
|
||||
|
||||
def _process_match_none(self):
|
||||
return Q(pk__in=[])
|
||||
|
||||
def _connect_filters(self, filters, connector, negated):
|
||||
if connector == "AND":
|
||||
q = Q(*filters)
|
||||
|
|
|
@ -561,6 +561,9 @@ class PostgresSearchQueryCompiler(BaseSearchQueryCompiler):
|
|||
lhs = field.get_attname(self.queryset.model) + "__" + lookup
|
||||
return Q(**{lhs: value})
|
||||
|
||||
def _process_match_none(self):
|
||||
return Q(pk__in=[])
|
||||
|
||||
def _connect_filters(self, filters, connector, negated):
|
||||
if connector == "AND":
|
||||
q = Q(*filters)
|
||||
|
|
|
@ -580,6 +580,9 @@ class SQLiteSearchQueryCompiler(BaseSearchQueryCompiler):
|
|||
lhs = field.get_attname(self.queryset.model) + "__" + lookup
|
||||
return Q(**{lhs: value})
|
||||
|
||||
def _process_match_none(self):
|
||||
return Q(pk__in=[])
|
||||
|
||||
def _connect_filters(self, filters, connector, negated):
|
||||
if connector == "AND":
|
||||
q = Q(*filters)
|
||||
|
|
|
@ -565,6 +565,9 @@ class Elasticsearch7SearchQueryCompiler(BaseSearchQueryCompiler):
|
|||
}
|
||||
}
|
||||
|
||||
def _process_match_none(self):
|
||||
return {"bool": {"mustNot": {"match_all": {}}}}
|
||||
|
||||
def _connect_filters(self, filters, connector, negated):
|
||||
if filters:
|
||||
if len(filters) == 1:
|
||||
|
|
|
@ -638,6 +638,13 @@ class BackendTests(WagtailTestUtils):
|
|||
],
|
||||
)
|
||||
|
||||
def test_filter_none(self):
|
||||
results = self.backend.search(MATCH_ALL, models.Book.objects.none())
|
||||
self.assertListEqual(list(results), [])
|
||||
|
||||
results = self.backend.search("JavaScript", models.Book.objects.none())
|
||||
self.assertListEqual(list(results), [])
|
||||
|
||||
# FACET TESTS
|
||||
|
||||
def test_facet(self):
|
||||
|
|
Ładowanie…
Reference in New Issue