2011-08-12 27 views
10

Tôi đang sử dụng Haystack và bất ngờ tới thăm với DjangoHaystack - Tại sao RealtimeSearchIndex đôi khi không cập nhật đối tượng lưu của tôi

Trong search_index.py Tôi có điều này

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) 

mẫu của tôi trông như thế này

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

Nếu tôi lưu Trang có tên hoặc mô tả được cập nhật thì nó sẽ cập nhật ngay lập tức và bao gồm các biến từ get_variables.items trong mẫu. Tuy nhiên nếu tôi cập nhật chỉ biến thì nó không cập nhật.

Có phải vì biến là một đối tượng khác có liên quan đến nó và mặc dù tôi đang lưu trên cùng một trang nhưng nó không nhận được thay đổi đối với Trang? Nếu vậy làm cách nào để buộc cập nhật mục Trang khi tôi đang cập nhật các đối tượng liên quan?

+0

Bạn đã bao giờ tìm một giải pháp cho điều này? Tôi đang gặp vấn đề tương tự, và tôi cho rằng nó có thể không được xây dựng vào Django Haystack ở giai đoạn này (nhưng tôi sẽ xem xét nó). –

Trả lời

6

A RealTimeSearchIndex chỉ cập nhật chỉ mục tìm kiếm khi mô hình được đăng ký được lưu hoặc xóa hoặc chính xác hơn khi tín hiệu post_save/post_delete của mô hình được phát ra. Các tín hiệu này không được phát ra nếu một mô hình liên quan bị xóa/lưu hoặc khi thực hiện một thao tác cập nhật/xóa hàng loạt.

Để giải quyết vấn đề của bạn, bạn có thể tạo một lớp con của RealTimeSearchIndex cũng cập nhật chỉ mục trên post_save/post_delete tín hiệu của mô hình liên quan.

8

Tôi đồng ý với Daniel Hepper, nhưng tôi nghĩ giải pháp dễ nhất ở đây là đính kèm người nghe vào tín hiệu post_save của mô hình liên quan của bạn (xem https://docs.djangoproject.com/en/dev/topics/signals/) và trong đó, kết nối lại mô hình.

ví dụ, trong myapp/models.py, trao MyRelatedModel mô hình trong đó có một ForeignKey để 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

Chỉ cần một lưu ý cho nhiều người xem gần đây của bài viết này ---- RealTimeSearchIndex đã bị phản đối.

Xem here cho bài đăng Haystack về nó.

4

Đối với khán giả gần đây, đây là một giải pháp dựa trên RealtimeSignalProcessor mới:

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

Trong settings.py:

HAYSTACK_SIGNAL_PROCESSOR = 'myapp.signals.RelatedRealtimeSignalProcessor' 

Trong mô hình. py:

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

    page = models.ForeignKey(Page) 

Bây giờ khi một Biến được lưu, chỉ mục cho Trang liên quan cũng sẽ được cập nhật.

(TODO:.. Điều này không làm việc cho các mối quan hệ mở rộng như foo__bar, hoặc cho nhiều-nhiều lĩnh vực Nhưng nó phải được đơn giản để mở rộng nó để xử lý những nếu bạn cần)

+0

Điều này sẽ được đánh dấu là câu trả lời được chấp nhận. – aabele

Các vấn đề liên quan