Fixed #31340 -- Allowed query expressions in SearchQuery.value and __search lookup.

This commit is contained in:
Baptiste Mispelon 2020-03-04 13:33:12 +01:00 committed by Mariusz Felisiak
parent 924c01ba09
commit 3baf92cf82
6 changed files with 43 additions and 4 deletions

View File

@ -11,7 +11,7 @@ class SearchVectorExact(Lookup):
lookup_name = 'exact'
def process_rhs(self, qn, connection):
if not hasattr(self.rhs, 'resolve_expression'):
if not isinstance(self.rhs, (SearchQuery, CombinedSearchQuery)):
config = getattr(self.lhs, 'config', None)
self.rhs = SearchQuery(self.rhs, config=config)
rhs, rhs_params = super().process_rhs(qn, connection)
@ -170,7 +170,8 @@ class SearchQuery(SearchQueryCombinable, Func):
self.function = self.SEARCH_TYPES.get(search_type)
if self.function is None:
raise ValueError("Unknown search_type argument '%s'." % search_type)
value = Value(value)
if not hasattr(value, 'resolve_expression'):
value = Value(value)
expressions = (value,)
self.config = SearchConfig.from_parameter(config)
if self.config is not None:

View File

@ -35,6 +35,10 @@ query and the vector.
To use the ``search`` lookup, ``'django.contrib.postgres'`` must be in your
:setting:`INSTALLED_APPS`.
.. versionchanged:: 3.1
Support for query expressions was added.
``SearchVector``
================
@ -108,7 +112,8 @@ See :ref:`postgresql-fts-search-configuration` for an explanation of the
.. versionchanged:: 3.1
Support for ``'websearch'`` search type was added.
Support for ``'websearch'`` search type and query expressions in
``SearchQuery.value`` were added.
``SearchRank``
==============

View File

@ -113,9 +113,14 @@ Minor features
* :class:`~django.contrib.postgres.search.SearchQuery` now supports
``'websearch'`` search type on PostgreSQL 11+.
* :class:`SearchQuery.value <django.contrib.postgres.search.SearchQuery>` now
supports query expressions.
* The new :class:`~django.contrib.postgres.search.SearchHeadline` class allows
highlighting search results.
* :lookup:`search` lookup now supports query expressions.
:mod:`django.contrib.redirects`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -185,6 +185,17 @@ class Migration(migrations.Migration):
},
bases=None,
),
migrations.CreateModel(
name='LineSavedSearch',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('line', models.ForeignKey('postgres_tests.Line', on_delete=models.CASCADE)),
('query', models.CharField(max_length=100)),
],
options={
'required_db_vendor': 'postgresql',
},
),
migrations.CreateModel(
name='AggregateTestModel',
fields=[

View File

@ -139,6 +139,11 @@ class Line(PostgreSQLModel):
return self.dialogue or ''
class LineSavedSearch(PostgreSQLModel):
line = models.ForeignKey('Line', models.CASCADE)
query = models.CharField(max_length=100)
class RangesModel(PostgreSQLModel):
ints = IntegerRangeField(blank=True, null=True)
bigints = BigIntegerRangeField(blank=True, null=True)

View File

@ -10,7 +10,7 @@ from django.db.models import F
from django.test import modify_settings, skipUnlessDBFeature
from . import PostgreSQLSimpleTestCase, PostgreSQLTestCase
from .models import Character, Line, Scene
from .models import Character, Line, LineSavedSearch, Scene
try:
from django.contrib.postgres.search import (
@ -110,6 +110,18 @@ class SimpleSearchTest(GrailTestData, PostgreSQLTestCase):
)
self.assertSequenceEqual(searched, [self.verse2])
def test_search_with_F_expression(self):
# Non-matching query.
LineSavedSearch.objects.create(line=self.verse1, query='hearts')
# Matching query.
match = LineSavedSearch.objects.create(line=self.verse1, query='elbows')
for query_expression in [F('query'), SearchQuery(F('query'))]:
with self.subTest(query_expression):
searched = LineSavedSearch.objects.filter(
line__dialogue__search=query_expression,
)
self.assertSequenceEqual(searched, [match])
@modify_settings(INSTALLED_APPS={'append': 'django.contrib.postgres'})
class SearchVectorFieldTest(GrailTestData, PostgreSQLTestCase):