From 1b4751257fb0b7ea1fde7e2eef7332a184058033 Mon Sep 17 00:00:00 2001 From: Daniel Lindsley Date: Tue, 26 Oct 2010 19:43:46 -0500 Subject: [PATCH] Fetching a list of all fields now produces correct results regardless of dict-ordering. Thanks to carljm & veselosky for the report! --- haystack/fields.py | 5 +++++ haystack/sites.py | 22 +++++++++++++++++----- tests/core/tests/sites.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/haystack/fields.py b/haystack/fields.py index dc7bf5512..814c4335e 100644 --- a/haystack/fields.py +++ b/haystack/fields.py @@ -30,6 +30,7 @@ def __init__(self, model_attr=None, use_template=False, template_name=None, self._default = default self.null = null self.index_fieldname = index_fieldname + self.is_multivalued = False self.set_instance_name(None) @@ -203,6 +204,10 @@ def convert(self, value): class MultiValueField(SearchField): + def __init__(self, **kwargs): + super(MultiValueField, self).__init__(**kwargs) + self.is_multivalued = True + def prepare(self, obj): return self.convert(super(MultiValueField, self).prepare(obj)) diff --git a/haystack/sites.py b/haystack/sites.py index 283b5dbc8..e2c5206fa 100644 --- a/haystack/sites.py +++ b/haystack/sites.py @@ -97,11 +97,17 @@ def all_searchfields(self): if not field_object.index_fieldname in fields: fields[field_object.index_fieldname] = field_object else: - # FIXME: This needs to handle verifying the field type is - # the same. - # FIXME: This needs to handle some of the other field - # options, like ``use_template``. - + # If the field types are different, we can mostly + # safely ignore this. The exception is ``MultiValueField``, + # in which case we'll use it instead, copying over the + # values. + if field_object.is_multivalued == True: + old_field = fields[field_object.index_fieldname] + fields[field_object.index_fieldname] = field_object + + # Switch it so we don't have to dupe the remaining + # checks. + field_object = old_field # We've already got this field in the list. Ensure that # what we hand back is a superset of all options that @@ -114,6 +120,12 @@ def all_searchfields(self): if field_object.faceted is True: fields[field_object.index_fieldname].faceted = True + + if field_object.use_template is True: + fields[field_object.index_fieldname].use_template = True + + if field_object.null is True: + fields[field_object.index_fieldname].null = True return fields diff --git a/tests/core/tests/sites.py b/tests/core/tests/sites.py index 355deacbe..7a31040d7 100644 --- a/tests/core/tests/sites.py +++ b/tests/core/tests/sites.py @@ -41,6 +41,12 @@ class AlternateValidSearchIndex(SearchIndex): title = CharField(faceted=True) +class MultiValueValidSearchIndex(SearchIndex): + text = CharField(document=True) + author = MultiValueField(stored=False) + title = CharField(indexed=False) + + class SearchSiteTestCase(TestCase): def setUp(self): super(SearchSiteTestCase, self).setUp() @@ -124,6 +130,7 @@ def test_all_searchfields(self): self.assertEqual(fields['author'].document, False) self.assertEqual(fields['author'].use_template, False) self.assertEqual(fields['author'].faceted, True) + self.assertEqual(fields['author'].stored, True) self.assertEqual(fields['author'].index_fieldname, 'author') self.site.unregister(MockModel) @@ -152,6 +159,29 @@ def test_all_searchfields(self): self.assertEqual(fields['name'].faceted, False) self.assertEqual(fields['name'].index_fieldname, 'name') + self.site.unregister(AnotherMockModel) + self.site.register(AnotherMockModel, MultiValueValidSearchIndex) + fields = self.site.all_searchfields() + self.assertEqual(len(fields), 4) + self.assertEqual(sorted(fields.keys()), ['author', 'name', 'text', 'title']) + self.assert_('text' in fields) + self.assert_(isinstance(fields['text'], CharField)) + self.assertEqual(fields['text'].document, True) + self.assertEqual(fields['text'].use_template, False) + self.assert_('title' in fields) + self.assert_(isinstance(fields['title'], CharField)) + self.assertEqual(fields['title'].document, False) + self.assertEqual(fields['title'].use_template, False) + self.assertEqual(fields['title'].faceted, True) + self.assertEqual(fields['title'].indexed, True) + self.assert_('author' in fields) + self.assert_(isinstance(fields['author'], MultiValueField)) + self.assertEqual(fields['author'].document, False) + self.assertEqual(fields['author'].use_template, False) + self.assertEqual(fields['author'].stored, False) + self.assertEqual(fields['author'].faceted, False) + self.assertEqual(fields['author'].index_fieldname, 'author') + self.site.unregister(AnotherMockModel) self.site.register(AnotherMockModel, InvalidSearchIndex) self.assertRaises(SearchFieldError, self.site.all_searchfields)