django-haystack / django-haystack/django-haystack
Nested model_attr lookup doesn't work as expected with iterable fields
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 3.7k
- Forks
- 1.3k
- Avg merge
- 3h 18m
- Merged PRs (30d)
- 3
Description
2a450d8 changed how nested model_attr lookups work such that if a model field is iterable, a nested lookup may fail.
- Tested with the latest Haystack release
- Tested with the current Haystack master branch
Expected behaviour
Indexing a nested attribute of an iterable field should work.
Actual behaviour
Indexing a nested attribute of an iterable field does not work in some cases, specifically with GeoDjango PointFields (and probably with any field type that is iterable).
Steps to reproduce the behaviour
- Create a model with a GeoDjango
GeometryField(e.g.,geom = models.PointField()) - Create a
SearchIndexfor that model with a field likelongitude = indexes.FloatField(model_attr='geom__x', indexed=False) - Index the model using
manage.py rebuild_index rebuild_indexfails with a message like "haystack.exceptions.SearchFieldError: The model '-122.67912' does not have a model_attr 'x'." (this happens becauseSearchField.resolve_attributes_lookup()iterates over thexandyfields of GeoDjangoPoints)
Configuration
- Operating system version: N/A
- Search engine version: N/A
- Python version: 3
- Django version: 1.8.13
- Haystack version: 2.5.0
I don't understand what 2a450d8 meant to do beyond supporting many-to-many fields, so I'm not sure what a proper fix would be, but here's a hacky fix that works for my specific use case (but causes some of the tests introduced in 2a450d8 to fail):
diff --git a/haystack/fields.py b/haystack/fields.py
index 0fa1abc..25adb54 100644
--- a/haystack/fields.py
+++ b/haystack/fields.py
@@ -153,7 +153,7 @@ class SearchField(object):
return current_objects.all()
return []
- elif not hasattr(current_objects, '__iter__'):
+ else:
current_objects = [current_objects]
return current_objects
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in haystack/fields.py at SearchField.resolve_attributes_lookup(), then inspect the tests introduced by commit 2a450d8. Reproduce the GeoDjango PointField case from the issue and run the affected tests. Done means nested model_attr lookup works for iterable fields while the existing many-to-many behavior remains passing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- backend, search
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100