2013-10-07 126 views
6

试图通过布尔值过滤SearchQuerySet对我无效。 (我用的是提供“简单”的后台搜索引擎,而测试。)Django Haystack - 如何过滤布尔字段的搜索结果?

我有这样一个指标:

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选项设置为Yes或No,我总是得到0个结果,这显然是错误的。我也尝试了壳,没有运气。 sqs.filter(has_been_sent=True)sqs.filter(has_been_sent=False)都返回一个空列表,即使如此sqs.values('has_been_sent')清楚地显示has_been_sent True值的一堆记录。更奇怪的是,sqs.filter(has_been_sent='t')返回记录的子集,以及'f','a'和无关字母'j'!我处于全面亏损状态。 Haystack有没有人遇到过这种问题?

在相关说明上,是您通过SearchQuerySet().filter()从索引字段(在search_indexes.py中)或模型字段(在各自的models.py中)过滤的字段?

编辑:

我一直在试图通过Django的manage.py shell来测试我的过滤器,但我觉得我做错了。它似乎没有跟随我的search_indexes.py,因为我将它限制在MyModel的一个子集中,并使用了index_queryset()方法,但是我在shell中获得了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'的结果不加起来,它应该如此,因为所有记录都需要布尔字段。我在测试中错过了一步吗?

回答

1

看来问题出在简单的后端。我安装并将Haystack转换到了Whoosh,并解决了这个问题。 (NowQueryQuerySet()。models()不起作用,但这显然是Haystack + Whoosh的一个记录错误。)

编辑:由于进一步的问题与转换,我切换到使用Solr 4.5.1作为我的后端。一切都如预期般运作。

6

试图筛选作为查询字符串truefalse,这一直是大海捞针已知的限制,我不知道这是固定的,而不是做:

sqs.filter(has_been_sent=True) 

这样做:

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

PS当你做SearchQuerySet().filter()你根据在search_indexes.py文件中定义的字段进行过滤。

+0

嗯。 “真”和“假”我仍然得到一个空的结果。我想我必须通过manage.py shell进行错误的测试。我编辑了我的主要帖子,以显示我如何测试。我想我一定错过了一步。 – Goluxas

+0

我建议你在模型或'search_indexes.py'文件中为布尔字段添加默认值,然后分别运行命令rebuild_index和update_index,然后再次按照我的建议进行测试。 –

相关问题