Fixes the PostgreSQL search backend broken by 25901aa.

pull/4059/head
Bertrand Bordage 2018-01-03 19:11:44 +01:00
rodzic e87ff07e7b
commit 379c027e1e
3 zmienionych plików z 23 dodań i 16 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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()

Wyświetl plik

@ -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