Django Haystack飞快多语言网站

时间:2013-04-06 23:29:46

标签: django django-haystack whoosh

我在django项目中使用haystack和whoosh后端。我的模型与模型转换模块是多语言的,它为名为title的字段创建自动字段,如title_tr,title_en ......

我试图让搜索意识到已经搜索到网络的所选语言并写下以下行,但它不适用于title_tr,entry_tags_tr字段......     #search_indexes.py

from haystack import indexes
from aksak.blog.models import Entry

class EntryIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(model_attr='descr_en', document=True, use_template=True)
    text_tr = indexes.CharField(model_attr='descr_tr')
    title_en = indexes.CharField(model_attr='title_en')
    title_tr = indexes.CharField(model_attr='title_tr')
    tags = indexes.MultiValueField(indexed=True, stored=True, model_attr='entry_tags')

    def get_model(self):
        return Entry


    # haystackCustomQuery.py  !!! IN URLS.PY I AM USING THIS CUSTOM VIEW <-------------

    from django.conf import settings
    from django.utils.translation import get_language
    from haystack.query import SearchQuerySet, DEFAULT_OPERATOR

    class MlSearchQuerySet(SearchQuerySet):
        def filter(self, **kwargs):
            if 'content' in kwargs:
                kwd = kwargs.pop('content')
                currentLngCode = str(get_language())
                lngCode = settings.LANGUAGE_CODE
                if currentLngCode == lngCode: 
                    kwdkey = "text" 
                    kwargs[kwdkey] = kwd
                else:
                    kwdkey = "text_%s" % currentLngCode
                    kwargs[kwdkey] = kwd


            if getattr(settings, 'HAYSTACK_DEFAULT_OPERATOR', DEFAULT_OPERATOR) == 'OR':
               return self.filter_or(**kwargs)
            else:
                return self.filter_and(**kwargs)

1 个答案:

答案 0 :(得分:3)

不确定,但我认为它可能与您的model_attr子类的SearchIndex参数有关,而这些参数未被haystack正确解析。尝试定义一些prepare_<index_fieldname>方法。

我包括我在(德语/英语)项目中使用的完整示例。就像你一样,受到search functionality on multi-language django site的启发,我得到了当前语言并将其映射到SearchIndex字段:

from django.conf import settings
from modeltranslation.utils import get_language
from modeltranslation.settings import DEFAULT_LANGUAGE
from haystack.query import SearchQuerySet, DEFAULT_OPERATOR

class ModeltranslationSearchQuerySet(SearchQuerySet):
    def filter(self, **kwargs):
        if 'content' in kwargs:
            kwd = kwargs.pop('content')
            lang = get_language()
            if lang != DEFAULT_LANGUAGE:
                kwdkey = "text_%s" % lang
                kwargs[kwdkey] = kwd
            else:
                kwargs['text'] = kwd
        if getattr(settings, 'HAYSTACK_DEFAULT_OPERATOR', DEFAULT_OPERATOR) == 'OR':
            return self.filter_or(**kwargs)
        else:
            return self.filter_and(**kwargs)

从本质上讲,每种语言都有一个SearchIndex字段,每个字段都有自己的prepare_<index_fieldname>方法。这是我的search_indexes.py的简化版本 - 它不是非常通用的,但对我的简单要求效果很好:

from haystack import indexes

class ContentIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.EdgeNgramField(document=True)  # German (default language)
    text_en = indexes.EdgeNgramField()  # English

    def prepare_text(self, obj):
        return '%s %s' % (obj.title_de, obj.descr_de)

    def prepare_text_en(self, obj):
        return '%s %s' % (obj.title_en, obj.descr_en)

注意,这里使用text而不是text_de作为带有document=True的索引字段,因为它是干草堆的约定(你做对了)。但在prepare_<index_fieldname>方法中,使用了实际的翻译字段名。它也不使用模板,而是使用简单的字符串连接。

haystack中包含的通用SearchView(我使用2.0.0-beta)采用searchquery参数,因此ModeltranslationSearchQuerySet可以直接通过网址传递 像这样设置(据我所知你有):

from haystack.forms import ModelSearchForm

url(r'^search/$', SearchView(
    searchqueryset=ModeltranslationSearchQuerySet(), form_class=ModelSearchForm))

最后说明:我暂时没有使用该代码,而模型转换在当前语言意识方面有一些重大变化。很可能它可以简化为模型转换&gt; = 0.6。