簡體   English   中英

在Haystack搜索中排除對象而無需update_index

[英]Exclude objects on Haystack search without the need of update_index

我需要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_index ,這使得它很糟糕。

如何在不需要運行任何其他東西的情況下制作它?

筆記:

Haystack的索引適用於許多模型,如下所示:

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

返回多種對象而不僅僅是一種模型。

謝謝

我最近不得不做類似的事情,這是一個痛苦的屁股。 我找不到任何其他方法來做到這一點。

首先解決Haystack在許多模型上工作的問題,因此過濾器返回所有匹配:

Haystack使用其索引名為django_ct的屬性處理幕后模型過濾,該屬性等於應用程序名稱和模型名稱。 在我的特殊情況下,它看起來像django_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)

當然,您可以將最后兩個查詢組合在一起,我只是將它們拆分為顯式。

這不是那么多代碼,但是由於各種原因我花了很長時間才使它工作。 希望它可以幫助你。

從haystack 2.4.0開始,你可以引發haystack.exceptions.SkipDocument來跳過使用index_queryset輕松排除的單個記錄

https://github.com/django-haystack/django-haystack/releases/tag/v2.4.0

有一種方法可以通過Haystack中的對象進行過濾。 我有一個與上面類似的問題,並且在Haystack SearchQuerySet API文檔中遇到了models方法。

來自Haystack( http://django-haystack.readthedocs.org/en/latest/searchqueryset_api.html#models

SearchQuerySet.models(self, *models)

接受任意數量的Model類以包含在搜索中。 這會縮小搜索結果范圍,使其僅包含指定模型的結果。

例:

SearchQuerySet().filter(content='foo').models(BlogEntry, Comment)

因此,您可以根據需要按對象內容進行過濾。

感謝@SI Eric,我能夠找到答案,它也有點hacky但它​​確實有效。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM