Search code examples
pythondjangodjango-haystack

How to filter Haystack SearchQuerySets by related models


How do you filter/join a Haystack SearchQuerySet by related model fields?

I have a query like:

sqs = SearchQuerySet().models(models.Person)

and this returns the same results that the equivalent admin page returns.

However, if I try and filter by model records linked by a foreign key:

sqs = sqs.filter(workplace__role__name='teacher')

it returns nothing, even though the page /admin/myapp/person/?workplace__role__name=teacher returns several records.

I don't want to do any full-text searching of these related models. I only want to do a simple exact-match filter. Is that possible with Haystack?


Solution

  • You cannot perform joins using a search engine like the ones supported by haystack. To make queries like this you need to add the information you want to filter on in a "denormalized" fashion in your search index:

    class ProfileIndex(indexes.SearchIndex, indexes.Indexable):
        # your other fields, most likely model attributes
        role_name = indexes.CharField()
    
        def get_model(self):
            return Person
    
        def prepare_role_name(self, person):
            return person.workplace.role_name
    

    Then you can filter on a field role_name. Just make sure to update your index if eg. the name changes, then you have to update all the according entries in the search index.