1

我在我的 django 项目中使用带有 whoosh 后端的 haystack。我的模型是多语言的模型翻译模块,它为名为 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)
4

1 回答 1

4

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

我包含了我在(德语/英语)项目中使用的完整示例。就像您一样,受多语言 django 网站上的搜索功能的启发,我得到了当前语言并将其映射到一个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因为它是 haystack 的约定(你说得对)。但是在prepare_<index_fieldname>方法内部使用了实际的翻译字段名。它也不使用模板,而是简单的字符串连接。

haystack 中包含的泛型SearchView(我使用 2.0.0-beta)需要一个searchquery参数,因此ModeltranslationSearchQuerySet可以像这样直接通过 urls 设置传递(据我所知,你有那个):

from haystack.forms import ModelSearchForm

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

最后说明:我有一段时间没有使用该代码,并且模型翻译在当前语言意识方面发生了一些重大变化。对于模型转换> = 0.6,它可能会被简化一点。

于 2013-04-10T15:06:40.430 回答