2011-08-12 9 views
10

estoy usando Haystack y Whoosh con DjangoHaystack - ¿Por qué RealtimeSearchIndex veces no actualiza mi objeto salvado

Dentro search_index.py tengo este

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) 

Mi plantilla se parece a esto

{{ object.name }} 
{{ object.description }} 
{{ object.template|striptags }} 
{% for k,v in object.get_variables.items %} 
{{ v }} 
{% endfor %} 

Si guardo la página con un nombre actualizado o una descripción, se actualiza inmediatamente e incluye las variables de get_variables.items en la plantilla. Sin embargo, si actualizo solo la variable, entonces no se actualiza.

¿Es porque la variable es otro objeto que está relacionado con ella y aunque estoy guardando en la misma página, no recoge un cambio en la Página? Si es así, ¿cómo obligo a actualizar el elemento de la página cuando estoy actualizando objetos relacionados?

+0

¿Alguna vez encontrar una solución a esto? Estoy teniendo el mismo problema, y ​​supongo que podría no estar incluido en Django Haystack en esta etapa (pero lo investigaré). –

Respuesta

6

Un RealTimeSearchIndex sólo actualiza el índice de búsqueda cuando un modelo que se ha registrado en el se guarda o se elimina, o para ser más precisos, cuando se emite la señal del modelo post_save/post_delete. Estas señales no se emiten si se borra/guarda un modelo relacionado o cuando se ejecuta una operación de actualización/eliminación masiva.

Para resolver su problema, podría crear una subclase de RealTimeSearchIndex que también actualice el índice en las señales post_save/post_delete del modelo relacionado.

8

Estoy de acuerdo con Daniel Hepper, pero creo que la solución más fácil aquí es conectar un oyente a la señal de post_save de su modelo relacionado (consulte https://docs.djangoproject.com/en/dev/topics/signals/) y en eso, reindexar el modelo.

por ejemplo, en miaplicacion/models.py, MyRelatedModel modelo dado que tiene un ForeignKey a 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) 
5

Sólo una nota para los espectadores más recientes de este post ---- RealTimeSearchIndex ya no se utiliza.

Consulte here para la publicación Haystack al respecto.

4

Para los espectadores recientes, he aquí una solución basada en el nuevo RealtimeSignalProcessor:

En miaplicacion/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) 

En settings.py:

HAYSTACK_SIGNAL_PROCESSOR = 'myapp.signals.RelatedRealtimeSignalProcessor' 

En modelos. PY:

class Variable(models.Model): 
    reindex_related = ('page',) 

    page = models.ForeignKey(Page) 

Ahora cuando se guarda una variable, también se actualizará el índice de la página relacionada.

(TODO:.. Esto no funciona para las relaciones extendidas como foo__bar, o para-muchos-a-muchos campos Pero debe ser sencillo para extenderlo para manejar los si es necesario)

+0

Esto debe marcarse como respuesta aceptada. – aabele

Cuestiones relacionadas