Стог сена - почему RealtimeSearchIndex иногда не обновляет мой сохраненный объект - PullRequest
10 голосов
/ 12 августа 2011

Я использую Haystack and 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 ]

8 голосов
/ 10 февраля 2012

Я согласен с Дэниелом Хеппером , но я думаю, что самое простое решение здесь - подключить слушателя к сигналу 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)
6 голосов
/ 03 февраля 2012

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

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

5 голосов
/ 19 августа 2013

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

См. здесь , чтобы узнать о стоге сена.

4 голосов
/ 05 января 2014

Для недавних зрителей вот решение на основе нового RealtimeSignalProcessor:

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

...