Haystack - Why does RealtimeSearchIndex sometimes not update my saved object

谁都会走 提交于 2019-12-03 11:38:15
Greg

I concur with Daniel Hepper, but I think the easiest solution here is to attach a listener to your related model's post_save signal (see https://docs.djangoproject.com/en/dev/topics/signals/) and in that, reindex the model.

E.g, in myapp/models.py, given model MyRelatedModel which has a foreignkey to 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)

A RealTimeSearchIndex only updates the search index when a model it is registered on is saved or deleted, or to be more precise, when the post_save/post_delete signal of the model is emitted. These signals are not emitted if a related model is deleted/saved or when a bulk update/delete operation is executed.

To solve your problem, you could create a subclass of RealTimeSearchIndex that also updates the index on post_save/post_delete signals of the related model.

Just a note for more recent viewers of this post ---- RealTimeSearchIndex has been deprecated.

See here for the Haystack post about it.

For recent viewers, here's a solution based on the new RealtimeSignalProcessor:

In 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)

In settings.py:

HAYSTACK_SIGNAL_PROCESSOR = 'myapp.signals.RelatedRealtimeSignalProcessor'

In models.py:

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

    page = models.ForeignKey(Page)

Now when a Variable is saved, the index for the related Page will also be updated.

(TODO: This doesn't work for extended relationships like foo__bar, or for many-to-many fields. But it should be straightforward to extend it to handle those if you need to.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!