2011-08-12 4 views
10

sto usando Pagliaio e Fruscio con DjangoHaystack - Perché RealtimeSearchIndex volte non aggiornare il mio oggetto salvato

Entro search_index.py ho questo

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) 

mio modello si presenta così

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

Se salvi la pagina con un nome o una descrizione aggiornati, essa viene immediatamente aggiornata e include le variabili di get_variables.items nel modello. Tuttavia, se aggiorno solo la variabile, non si aggiorna.

È perché la variabile è un altro oggetto a esso correlato e anche se sto salvando sulla stessa pagina non rileva una modifica alla Pagina? In tal caso, come posso forzare l'aggiornamento dell'elemento della pagina quando aggiorno gli oggetti correlati?

+0

avete fatto mai trovare una soluzione a questo? Sto avendo lo stesso problema, e suppongo che potrebbe non essere integrato in Django Haystack in questa fase (ma lo esaminerò). –

risposta

6

A RealTimeSearchIndex aggiorna solo l'indice di ricerca quando un modello su cui è registrato viene salvato o eliminato, o per essere più precisi, quando viene emesso il segnale post_save/post_delete del modello. Questi segnali non vengono emessi se un modello correlato viene cancellato/salvato o quando viene eseguita un'operazione di aggiornamento/eliminazione di massa.

Per risolvere il problema, è possibile creare una sottoclasse di RealTimeSearchIndex che aggiorna anche l'indice sui segnali post_save/post_delete del modello correlato.

8

Concordo con Daniel Hepper, ma penso che la soluzione più semplice qui sia quella di collegare un listener al segnale post_save del proprio modello correlato (vedere https://docs.djangoproject.com/en/dev/topics/signals/) e, in tal senso, reindicizzare il modello.

per esempio, in myapp/models.py, data MyRelatedModel modello che ha una ForeignKey per 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

Solo una nota per gli spettatori più recenti di questo post ---- RealTimeSearchIndex è stato sconsigliato.

Vedere here per il post Haystack su di esso.

4

Per ultimi gli spettatori, ecco una soluzione basata sul nuovo RealtimeSignalProcessor:

in 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) 

In settings.py:

HAYSTACK_SIGNAL_PROCESSOR = 'myapp.signals.RelatedRealtimeSignalProcessor' 

Nei modelli. py:

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

    page = models.ForeignKey(Page) 

Ora, quando viene salvata una variabile, verrà aggiornato anche l'indice della relativa pagina.

(TODO:.. Questo non funziona per i rapporti estesi come foo__bar, o per molti-a-molti campi, ma dovrebbe essere semplice da estenderla a gestire quelli se è necessario)

+0

Questo dovrebbe essere contrassegnato come risposta accettata. – aabele