Taggit и Haystack с RealtimeSignalProcessor
Пожалуйста, обратите внимание, что я использую эластичный поиск в качестве моего бэкэнда.
Теги Taggit, связанные с моей моделью ObjectA, по-видимому, не отображаются в моем индексе при использовании параметра django
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
Когда я перечисляю индексные документы, используя
http://localhost:9200/_search
и просмотрите индексную запись для экземпляра ObjectA, который я вставил в БД, элемент "tags" выглядит как
"tags": []
Это только после того, как я бегу
manage.py rebuild_index [or update_index]
теги появляются то есть
"tags": ["tag-a", "tag-b"]
Интересно, что "title", "description" отображаются автоматически без запуска rebuild_index / update_index.
objecta_text.txt
{{ object.title }}
{{ object.description }}
{% for tag in object.tags.all %} {{ tag.name }} {% endfor %}
search_indexes.py
class ObjectAIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
title = indexes.CharField(model_attr='title')
description = indexes.CharField(model_attr='description', null=True)
tags = indexes.MultiValueField()
def get_model(self):
return ObjectA
def prepare_tags(self, obj):
return [tag.name for tag in obj.tags.all()]
Любые предложения о том, как заставить теги отображаться в индексном документе, не вызывая rebuild_index?
1 ответ
Не уверен, что вы уже поняли это, но причина того, что ваш индекс не содержит тегов после сохранения, состоит в том, что они еще не сохранены, когда процессор сигналов обрабатывает обновление индекса. Один хакерский способ решить эту проблему - расширить haystack.signals.RealtimeSignalProcessor
запускать обновления связанных моделей. Вот пример, который обновит индекс для любой маркированной модели.
signals.py
from haystack.signals import RealtimeSignalProcessor
class RelatedRealtimeSignalProcessor(RealtimeSignalProcessor):
"""
Extension to haystack's RealtimeSignalProcessor not only causing the
search_index to update on saved model, but also for related effected models
"""
def handle_save(self, sender, instance, **kwargs):
super(RelatedRealtimeSignalProcessor, self).handle_save(
sender,
instance,
**kwargs
)
self.handle_related(sender, instance)
def handle_delete(self, sender, instance, **kwargs):
super(RelatedRealtimeSignalProcessor, self).handle_delete(
sender,
instance,
**kwargs
)
self.handle_related(sender, instance)
def handle_related(self, sender, instance):
for related in self.get_related_models(sender, instance):
super(RelatedRealtimeSignalProcessor, self).handle_save(
related['sender'],
related['instance']
)
def get_related_models(self, sender, instance):
from taggit.models import TaggedItem
related = []
if sender == TaggedItem:
related.append({
'sender': instance.content_object.__class__,
'instance': instance.content_object
})
return related
PS. Не забудьте обновить свой HAYSTACK_SIGNAL_PROCESSOR = '<app>.signals.RealtimeSignalProcessor'