From 90593c07b77e7b07f09f8416ea2fb5fab6680cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20K=C3=A1rolyi?= Date: Fri, 17 Mar 2023 14:53:24 +0100 Subject: [PATCH] Allow more internal data exact searches Bump version Fix syntax error Adjust CHANGELOG.rst Add test for __exact on ID --- CHANGELOG.rst | 1 + tests/xapian_tests/tests/test_query.py | 7 +++++++ xapian_backend.py | 4 +++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c0fa0b6..5ec1748 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,7 @@ xapian-haystack Changelog Unreleased ---------- +- Add DJANGO_CT, DJANGO_ID, ID to be used with '__exact' internally. - Dropped support for Python 3.6. - Fixed DatabaseLocked errors when running management commands with multiple workers. diff --git a/tests/xapian_tests/tests/test_query.py b/tests/xapian_tests/tests/test_query.py index 491a956..b217bc6 100644 --- a/tests/xapian_tests/tests/test_query.py +++ b/tests/xapian_tests/tests/test_query.py @@ -236,6 +236,13 @@ class XapianSearchQueryTestCase(HaystackBackendTestCase, TestCase): self.sq.add_filter(SQ(django_ct='time')) self.assertExpectedQuery(self.sq.build_query(), 'CONTENTTYPEtime') + def test_unphrased_id(self): + 'An internal ID should NOT be phrased so one can exclude IDs.' + self.sq.add_filter(SQ(id__in=['testing123', 'testing456'])) + expected = '(Qtesting123 OR Qtesting456)' + self.assertExpectedQuery( + query=self.sq.build_query(), string_or_list=expected) + class SearchQueryTestCase(HaystackBackendTestCase, TestCase): """ diff --git a/xapian_backend.py b/xapian_backend.py index d6a92bb..05e8fed 100755 --- a/xapian_backend.py +++ b/xapian_backend.py @@ -42,6 +42,8 @@ TERM_PREFIXES = { 'field': 'X' } +_EXACT_SEARCHFIELDS = frozenset((DJANGO_CT, DJANGO_ID, ID)) + MEMORY_DB_NAME = ':memory:' DEFAULT_XAPIAN_FLAGS = ( @@ -1437,7 +1439,7 @@ class XapianSearchQuery(BaseSearchQuery): Assumes term is not a list. """ - if field_type == 'text' and field_name not in (DJANGO_CT,): + if field_type == 'text' and field_name not in _EXACT_SEARCHFIELDS: term = '^ %s $' % term query = self._phrase_query(term.split(), field_name, field_type) else: