Django Haystack - Как отфильтровать результаты поиска по логическому полю?
Попытка отфильтровать SearchQuerySet по логическому значению не работает для меня. (Я использую предоставленную "Простую" бэкэнд-поисковую систему во время тестирования.)
У меня есть индекс, как:
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
И я использую пользовательскую форму для поиска:
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
Если я устанавливаю для параметра has_been_sent значение Да или Нет в форме, я всегда получаю 0 результатов, что явно неверно. Я тоже пробовал в скорлупе, без везения. sqs.filter(has_been_sent=True)
а также sqs.filter(has_been_sent=False)
оба возвращают пустой список, ДАЖЕ МЫСЛЬ sqs.values('has_been_sent')
четко показывает кучу записей со значениями True для has_been_sent. И даже незнакомец, sqs.filter(has_been_sent='t')
возвращает подмножество записей вместе с 'f', 'a' и несвязанными буквами, такими как 'j'! Я в полной растерянности. У кого-нибудь есть опыт решения подобных проблем с Хейстек?
В соответствующей заметке есть поля, по которым вы фильтруете SearchQuerySet().filter()
из полей индекса (в search_indexes.py) или из полей модели (в соответствующих им файлах models.py)?
РЕДАКТИРОВАТЬ:
Я пытался протестировать свои фильтры через оболочку manage.py в Django, но думаю, что я делаю это неправильно. Похоже, что он не следует моему search_indexes.py, поскольку я ограничил его подмножеством MyModel с помощью метода index_queryset(), но я получаю ВСЕ объекты MyModel в оболочке.
>>> from haystack.query import SearchQuerySet
>>> from myapp.models import MyModel
>>> sqs = SearchQuerySet().models(MyModel)
А потом немного тестирования:
>>> 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
Поскольку при фильтрации по поддельному полю я получаю подмножество, я не думаю, что он распознает has_been_sent как одно из моих полей фильтра. Тем более, что результаты для 't' и 'f' не суммируются с итогом, который он ДОЛЖЕН, так как это логическое поле является обязательным для всех записей. Я пропускаю шаг в моем тестировании?
2 ответа
Похоже, что проблема была в простом бэкэнде. Я установил и переключил Haystack на Whoosh, и эта проблема прояснилась. (Теперь SearchQuerySet(). Models() не работает, но это явно задокументированная ошибка с Haystack + Whoosh.)
Изменить: Из-за дальнейших проблем с Whoosh, я переключился на использование Solr 4.5.1 в качестве моего бэкэнда. Теперь все работает как положено.
Попробуйте отфильтровать как строку true
или же false
в запросе это было известным ограничением в стоге сена, и я не уверен, что это исправлено, вместо того, чтобы делать:
sqs.filter(has_been_sent=True)
Сделай это:
sqs.filter(has_been_sent='true') # true or false in lowercase
PS когда ты SearchQuerySet().filter()
Вы фильтруете на основе полей, определенных в search_indexes.py
файл.