From 379c027e1e35435138f766c91f49ab47e3e4a3ac Mon Sep 17 00:00:00 2001 From: Bertrand Bordage Date: Wed, 3 Jan 2018 19:11:44 +0100 Subject: [PATCH] Fixes the PostgreSQL search backend broken by 25901aa. --- wagtail/contrib/postgres_search/backend.py | 24 +++++++++++++++++-- .../postgres_search/tests/test_backend.py | 11 --------- wagtail/search/backends/db.py | 4 +--- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/wagtail/contrib/postgres_search/backend.py b/wagtail/contrib/postgres_search/backend.py index 2d90a99c28..d41b6b0ebc 100644 --- a/wagtail/contrib/postgres_search/backend.py +++ b/wagtail/contrib/postgres_search/backend.py @@ -3,7 +3,7 @@ from warnings import warn from django.contrib.postgres.search import SearchQuery as PostgresSearchQuery from django.contrib.postgres.search import SearchRank, SearchVector from django.db import DEFAULT_DB_ALIAS, NotSupportedError, connections, transaction -from django.db.models import F, Manager, TextField, Value +from django.db.models import F, Manager, TextField, Value, Q from django.db.models.constants import LOOKUP_SEP from django.db.models.functions import Cast from django.utils.encoding import force_text @@ -162,6 +162,9 @@ class Index: else: self.add_items_update_then_create(content_type_pk, objs, config) + def delete_item(self, item): + item.index_entries.using(self.db_alias).delete() + def __str__(self): return self.name @@ -245,6 +248,23 @@ class PostgresSearchQueryCompiler(BaseSearchQueryCompiler): queryset = queryset.order_by('-pk') return queryset[start:stop] + def _process_lookup(self, field, lookup, value): + return Q(**{field.get_attname(self.queryset.model) + + '__' + lookup: value}) + + def _connect_filters(self, filters, connector, negated): + if connector == 'AND': + q = Q(*filters) + elif connector == 'OR': + q = OR([Q(fil) for fil in filters]) + else: + return + + if negated: + q = ~q + + return q + class PostgresSearchResults(BaseSearchResults): def _do_search(self): @@ -329,7 +349,7 @@ class PostgresSearchBackend(BaseSearchBackend): self.get_index_for_object(obj_list[0]).add_items(model, obj_list) def delete(self, obj): - obj.index_entries.all().delete() + self.get_index_for_object(obj).delete_item(obj) SearchBackend = PostgresSearchBackend diff --git a/wagtail/contrib/postgres_search/tests/test_backend.py b/wagtail/contrib/postgres_search/tests/test_backend.py index d4a05e4296..dbeead789b 100644 --- a/wagtail/contrib/postgres_search/tests/test_backend.py +++ b/wagtail/contrib/postgres_search/tests/test_backend.py @@ -38,14 +38,3 @@ class TestPostgresSearchBackend(QueryAPITestMixin, BackendTests, TestCase): [(6, 'A'), (4, 'B'), (2, 'C'), (0, 'D')]) self.assertListEqual(determine_boosts_weights([-2, -1, 0, 1, 2, 3, 4]), [(4, 'A'), (2, 'B'), (0, 'C'), (-2, 'D')]) - - # Broken - # Note: This is applying the filter, but should be raising the FieldError instead - @unittest.expectedFailure - def test_filter_on_non_filterable_field(self): - super().test_filter_on_non_filterable_field() - - # Broken - @unittest.expectedFailure - def test_order_by_non_filterable_field(self): - super().test_order_by_non_filterable_field() diff --git a/wagtail/search/backends/db.py b/wagtail/search/backends/db.py index 45bf4081b5..b25aa669e0 100644 --- a/wagtail/search/backends/db.py +++ b/wagtail/search/backends/db.py @@ -36,9 +36,7 @@ class DatabaseSearchQueryCompiler(BaseSearchQueryCompiler): if connector == 'AND': q = models.Q(*filters) elif connector == 'OR': - q = models.Q(filters[0]) - for fil in filters[1:]: - q |= fil + q = OR([models.Q(fil) for fil in filters]) else: return