带有RealtimeSignalProcessor的Taggit和Haystack

时间:2014-01-14 04:50:03

标签: elasticsearch django-haystack django-taggit

请注意我使用elasticsearch作为我的后端。

与我的模型ObjectA相关联的Taggit标签似乎没有在我的索引中使用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 个答案:

答案 0 :(得分: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'