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