Haystack - 为什么RealtimeSearchIndex有时不会更新我保存的对象

时间:2011-08-12 14:34:57

标签: django-haystack

我正在使用Haystack和Whoosh与Django

在search_index.py中我有这个

class PageIndex(RealTimeSearchIndex):
    text = CharField(document=True, use_template=True)
    creator = CharField(model_attr='creator')
    created = DateTimeField(model_attr='created')
    org = CharField(model_attr='organisation')

site.register(Page, PageIndex)

我的模板看起来像这样

{{ object.name }}
{{ object.description }}
{{ object.template|striptags }}
{% for k,v in object.get_variables.items %}
{{ v }}
{% endfor %}

如果我使用更新的名称或描述保存页面,则会立即更新并包含模板中get_variables.items的变量。但是,如果我只更新变量,那么它就不会更新。

是因为变量是另一个与之相关的对象,即使我在同一页面上保存它也不会对页面进行更改吗?如果是这样,当我更新相关对象时,如何强制更新页面项?

4 个答案:

答案 0 :(得分:8)

我同意Daniel Hepper,但我认为这里最简单的解决方案是将监听器附加到相关模型的post_save信号(请参阅https://docs.djangoproject.com/en/dev/topics/signals/),然后重新索引模型。

例如,在myapp / models.py中,给定模型MyRelatedModel,它具有MyModel的外键

from myapp.search_indexes import MyModelIndex

def reindex_mymodel(sender, **kwargs):
    MyModelIndex().update_object(kwargs['instance'].mymodel)
models.signals.post_save.connect(reindex_mymodel, sender=MyRelatedModel)

答案 1 :(得分:6)

RealTimeSearchIndex仅在保存或删除注册模型时更新搜索索引,或者更准确地说,在发出模型的post_save/post_delete信号时更新搜索索引。如果删除/保存相关模型或执行批量更新/删除操作,则不会发出这些信号。

要解决您的问题,您可以创建RealTimeSearchIndex的子类,该子类还会更新相关模型的post_save/post_delete信号的索引。

答案 2 :(得分:5)

这篇文章的最近观众只是一个注释---- RealTimeSearchIndex已被弃用。

有关Haystack的帖子,请参阅here

答案 3 :(得分:4)

对于最近的观众,这是基于新的RealtimeSignalProcessor的解决方案:

在myapp / signals.py中:

class RelatedRealtimeSignalProcessor(RealtimeSignalProcessor):

    def handle_save(self, sender, instance, **kwargs):
        if hasattr(instance, 'reindex_related'):
            for related in instance.reindex_related:
                related_obj = getattr(instance, related)
                self.handle_save(related_obj.__class__, related_obj)
        return super(RelatedRealtimeSignalProcessor, self).handle_save(sender, instance, **kwargs)

    def handle_delete(self, sender, instance, **kwargs):
        if hasattr(instance, 'reindex_related'):
            for related in instance.reindex_related:
                related_obj = getattr(instance, related)
                self.handle_delete(related_obj.__class__, related_obj)
        return super(RelatedRealtimeSignalProcessor, self).handle_delete(sender, instance, **kwargs)

在settings.py中:

HAYSTACK_SIGNAL_PROCESSOR = 'myapp.signals.RelatedRealtimeSignalProcessor'

在models.py中:

class Variable(models.Model):
    reindex_related = ('page',)

    page = models.ForeignKey(Page)

现在保存变量时,相关页面的索引也会更新。

(TODO:这不适用于foo__bar之类的扩展关系,也不适用于多对多字段。但如果需要,可以直接扩展它以处理这些关系。)