Haystack - Почему RealtimeSearchIndex иногда не обновляет мой сохраненный объект

Я использую 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 в шаблоне. Однако, если я обновляю только переменную, то она не обновляется.

Это потому, что переменная - это другой объект, связанный с ней, и хотя я сохраняю ее на той же странице, она не получает изменения на странице? Если да, то каким образом я могу принудительно обновлять элемент страницы при обновлении связанных объектов?

Ответ 1

Я согласен с Daniel Hepper, но я думаю, что самым простым решением здесь является присоединение слушателя к соответствующему сигналу post_save модели (см. https://docs.djangoproject.com/en/dev/topics/signals/), и в этом, reindex модель.

Например, в 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)

Ответ 2

A RealTimeSearchIndex обновляет только индекс поиска, когда зарегистрированная модель сохраняется или удаляется, а точнее, когда выдается сигнал post_save/post_delete модели. Эти сигналы не выдаются, если связанная модель удаляется/сохраняется или когда выполняется операция массового обновления/удаления.

Чтобы решить вашу проблему, вы можете создать подкласс RealTimeSearchIndex, который также обновит индекс на post_save/post_delete сигналах соответствующей модели.

Ответ 3

Просто примечание для более свежих зрителей этого сообщения ---- RealTimeSearchIndex устарел.

Смотрите здесь для сообщения Haystack об этом.

Ответ 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, или для полей "многие-ко-многим". Но это должно быть просто, чтобы расширять его, чтобы обрабатывать их, если вам нужно.)