Python 排除Haystack搜索中的对象,而无需更新索引

Python 排除Haystack搜索中的对象,而无需更新索引,python,django,django-haystack,Python,Django,Django Haystack,我需要Haystack搜索来排除一些值为published=False的对象,到目前为止,我管理它的方法是添加一个exclude(published=True),如下所示: class MymodelIndex(indexes.RealTimeSearchIndex, indexes.Indexable): def get_queryset(self): return Mymodel.objects.all().exclude(published=False) 它按预期

我需要Haystack搜索来排除一些值为
published=False
的对象,到目前为止,我管理它的方法是添加一个
exclude(published=True)
,如下所示:

class MymodelIndex(indexes.RealTimeSearchIndex, indexes.Indexable):
    def get_queryset(self):
        return Mymodel.objects.all().exclude(published=False)
它按预期工作,问题是每次向数据库中添加新对象时,我都需要
/manage.py rebuild\u index
,这会让情况变得很糟糕

我怎样才能在不需要运行其他任何东西的情况下成功

注:

Haystack上的索引适用于许多模型,因此如下所示:

search = (
    SearchQuerySet().filter(content=term)
)
返回多种对象,而不仅仅是一个模型


谢谢

我最近不得不做一些类似的事情,这是一件很痛苦的事。我找不到其他方法来做这件事

首先要解决Haystack在许多模型上工作的问题,因此filter会返回所有匹配项:

Haystack使用一个名为django_ct的属性(等于app name和model name)对模型进行幕后过滤。在我的例子中,它看起来像是
django\u ct='books.Title'

您可以尝试通过执行以下操作进行过滤:

SearchQuerySet.filter(content=term, django_ct='app.Model')
但我不知道它是否会这样。在我的特殊情况下,我必须进行原始搜索,因此我能够直接将过滤添加到该搜索中:

sqs = SearchQuerySet()
sqs = sqs.raw_search(u'(title:(%s)^500 OR author:"%s"^400 OR "%s"~2 OR (%s)) AND (django_ct:books.Title)' % term)
无论您是如何获得它的,在您获得您想要在不更新索引的情况下对其执行附加筛选的
SearchQuerySet
之后,您必须使用自己的代码来执行此操作

# each item in a queryset has a pk property to the model instance it references
pks = [item.pk for item in list(sqs)] # have to wrap sqs in a list otherwise it causes problems

# use those pks to create a standard django queryset object
results = Model.objects.filter(pk__in=pks)

# Now you can do any additional filtering like normal
results = results.exclude(published=False)
当然,您可以组合最后两个查询,我只是将它们拆分为显式查询


虽然代码不多,但由于各种原因,我花了很长时间才让它正常工作。希望它能帮到你。

多亏了@SI Eric,我才找到了答案,虽然有点粗糙,但它还是有效的

search = (
    SearchQuerySet().filter(content=term)
)

search_list = search[:]
unpublished_Mymodels = Mymodel.objects.filter(published=False)

for match in search_list:
    try:
        if match.model_name == 'Mymodel':
            if match._get_object() in unpublished_Mymodels:
                search_list.remove(match)
    except:
        pass

search = search_list

有一种方法可以通过干草堆中的对象进行过滤。我遇到了与上面类似的问题,在Haystack
SearchQuerySet
API文档中遇到了
models
方法

来自干草堆()

SearchQuerySet.models(self,*models)

接受要包含在搜索中的任意数量的模型类。这将缩小搜索结果范围,使其仅包括指定型号的结果

例如:

SearchQuerySet().filter(content='foo').models(博客条目、评论)


因此,从这里您可以根据需要按对象内的内容进行过滤。

自haystack 2.4.0以来,您可以使用
haystack.exceptions.SkipDocument
跳过使用
index\u queryset


谢谢你的回答,我仍然认为这太过分了,必须有一种排除对象的方法。我希望有,我只是没有成功地找到一个。SearchQuerySet对象模仿Django QuerySet对象的某些功能,但它的功能有限。您能否解释一下为什么每次添加新对象时都需要重建索引?