以编程方式创建haystack索引

时间:2015-04-20 01:12:16

标签: python django django-haystack

创建Haystack搜索索引的标准方法是在search_indexes.py文件中,每个模型都要编译一个类,如下所示:

class FooIndex(indexes.Indexable):
    def get_model(self):
        return models.Foo

但是,我有很多模型都表现相似,我想索引它们(以及以其他方式注册)。

例如,给定此models.py代码:

class BaseModel(models.model):
   class Meta:
       abstract = True
   # some shared fields
class Foo(BaseModel):
  pass # some different fields
class Bar(BaseModel):
  pass

此代码有效:

def register_base_model(sub_class, *args, **kwargs):
    #other shared actions here
    admin.site.register(sub_class,BaseAdmin) # BaseAdmin defined elsewhere
register_base_model(models.Foo)

但这不会:

def register_base_model(sub_class, *args, **kwargs):
    #other shared actions here
    admin.site.register(sub_class,BaseAdmin) # BaseAdmin defined elsewhere
    class SubclassedIndex(indexes.SearchIndex,indexes.Indexable):
        def get_model(self):
            return sub_class

register_base_model(models.Foo)

因为课程SubclassedIndex仅在register_base_model的范围内。 Haystack 1.x曾经有一个register / unregister API,但现在已经不行了,虽然新方法大部分都比较简单,但我需要类似的行为。

如何在不依赖现在运行的自动化方式的情况下以编程方式注册HaystackIndex?

1 个答案:

答案 0 :(得分:0)

这可以通过至少一种方式完成,虽然采用非常 hacky方式。

首先,您必须拥有一个带有search_indexes.py模块的应用程序,并且必须在以编程方式添加索引的位置导入该应用程序:

from haystack import connections
from haystack.constants import DEFAULT_ALIAS

import my_app.search_indexes as search_index

for my_class in some_list_of_models:

    search_index_class_name = "%s_%sSearchIndex"%(concept_class._meta.app_label,concept_class.__name__)

    # Create a new subclass of search index (see below)
    # And monkey-patch it in.
    setattr(search_index, class_name, create(concept_class))

# Since we've added a new class, kill the index so it is rebuilt next time we access the index.
connections[DEFAULT_ALIAS]._index = None

然后你需要一个函数来构建类

def create(cls):
    class DynamicSearchIndex(indexes.SearchIndex, indexes.Indexable):
        # What ever fields are needed go here
        def get_model(self):
            return cls
    return SubclassedConceptIndex

我发现,您需要确保模板存在于正确的位置,并且可能需要添加try / except包装器以在构建类时捕获错误。