Django Haystack - How to filter search results by logical field?

Trying to filter a SearchQuerySet using a boolean does not work for me. (During testing, I use the provided β€œsimple” backend search engine.)

I have an index like:

class MyIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) has_been_sent = indexes.BooleanField(model_attr='has_been_sent') # other fields def get_model(self): return MyModel 

And I use a custom search form:

 BOOLEAN_OPTIONS = [ ('either', 'Either'), ('yes', 'Yes'), ('no', 'No') ] class MyModelSearchForm(SearchForm): # other fields has_been_sent = forms.ChoiceField( widget = forms.Select(), label = 'Sent?', choices=BOOLEAN_OPTIONS ) def search(self): sqs = super(MyModelSearchForm, self).search() if not self.is_valid(): return self.no_query_found() sqs = sqs.models(MyModel) # cuts out other models from the search results if self.cleaned_data['has_been_sent'] != 'either': if self.cleaned_data['has_been_sent'] == 'yes': sent = True else: sent = False sqs = sqs.filter(has_been_sent=sent) return sqs 

If I set the has_been_sent parameter to Yes or No on the form, I always get 0 results, which is clearly wrong. I also tried in the shell, with no luck. sqs.filter(has_been_sent=True) and sqs.filter(has_been_sent=False) both return an empty list, EVEN THOUGH sqs.values('has_been_sent') clearly shows a bunch of records with True values ​​for has_been_sent. And even a stranger, sqs.filter(has_been_sent='t') returns a subset of records, as well as "f", "a", and unrelated letters like "j"! I have a complete loss. Does anyone have experience with a similar issue with Haystack?

In the corresponding note, the fields that you filter through SearchQuerySet().filter() from the index fields (in search_indexes.py) or the model fields (in their respective models.py)?

EDIT:

I am trying to test my filters using the Django manage.py shell, but I think I'm doing it wrong. This doesn't seem to be like my search_indexes.py since I limited it to a subset of MyModel using the index_queryset () method, but I get ALL MyModel objects in the shell.

 >>> from haystack.query import SearchQuerySet >>> from myapp.models import MyModel >>> sqs = SearchQuerySet().models(MyModel) 

And then some testing:

 >>> len(sqs) # SHOULD be 5, due to the index_queryset() method I defined in search_indexes.py 17794 >>> sqs.filter(has_been_sent='true') # Same happens for True, 'TRUE', and all forms of false [] >>> len(sqs.filter(not_a_real_field='g')) # Made-up filter field, returns a subset somehow?? 2591 >>> len(sqs.filter(has_been_sent='t')) 3621 >>> len(sqs.filter(has_been_sent='f')) 2812 

Since I get a subset when filtering in a fake field, I don't think it recognized has_been_sent as one of the filter fields. Moreover, the results for 't' and 'f' are not cumulative with the sum that it SHOULD, since this Boolean field is required for all records. Did I miss a step in my testing?

+6
source share
2 answers

It seems that the problem was in the simplest backend. I installed and switched Haystack to Whoosh, and this problem cleared up. (Now SearchQuerySet (). Models () does not work, but this is apparently a documented bug with Haystack + Whoosh.)

Edit: due to further problems with Whoosh, I switched to using Solr 4.5.1 as my backend. Now everything works as expected.

+1
source

Try filtering as a true or false string in the request, this was a known limitation in the haystack, and I'm not sure if this is fixed, instead of doing:

 sqs.filter(has_been_sent=True) 

Do it:

 sqs.filter(has_been_sent='true') # true or false in lowercase 

PS, when you execute SearchQuerySet().filter() , you filter based on the fields defined in the search_indexes.py file.

+6
source

Source: https://habr.com/ru/post/955446/


All Articles