使 Django-haystack 自动完成建议适用于重音查询(à、é、ï 等)

问题描述 投票:0回答:1

我正在尝试使 Django-haystack 的自动完成功能的建议对包含重音符号的单词敏感。 (法语)


目前结果:

用户类型

Seville

输出建议不返回任何内容,因为实际目标名称是

Séville


预期结果:

用户类型

Seville

输出建议返回

Séville


我已阅读以下文档,但我仍然不确定如何实现此目的:https://django-haystack.readthedocs.io/en/master/searchqueryset_api.html#order-by

这是我的代码:

表格.py

from haystack.forms import FacetedSearchForm
from haystack.inputs import Exact


class FacetedProductSearchForm(FacetedSearchForm):

    def __init__(self, *args, **kwargs):
        data = dict(kwargs.get("data", []))
        self.ptag = data.get('ptags', [])
        self.q_from_data = data.get('q', '')
        super(FacetedProductSearchForm, self).__init__(*args, **kwargs)

    def search(self):
        sqs = super(FacetedProductSearchForm, self).search()

        # Ideally we would tell django-haystack to only apply q to destination
        # ...but we're not sure how to do that, so we'll just re-apply it ourselves here.
        q = self.q_from_data
        sqs = sqs.filter(destination=Exact(q))

        print('should be applying q: {}'.format(q))
        print(sqs)

        if self.ptag:
            print('filtering with tags')
            print(self.ptag)
            sqs = sqs.filter(ptags__in=[Exact(tag) for tag in self.ptag])

        return sqs

search_indexes.py

import datetime
from django.utils import timezone
from haystack import indexes
from haystack.fields import CharField

from .models import Product


class ProductIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.EdgeNgramField(
        document=True, use_template=True,
        template_name='search/indexes/product_text.txt')
    title = indexes.CharField(model_attr='title')
    description = indexes.EdgeNgramField(model_attr="description")
    destination = indexes.EdgeNgramField(model_attr="destination") #boost=1.125
    link = indexes.CharField(model_attr="link")
    image = indexes.CharField(model_attr="image")

    # Tags
    ptags = indexes.MultiValueField(model_attr='_ptags', faceted=True)

    # for auto complete
    content_auto = indexes.EdgeNgramField(model_attr='destination')

    # Spelling suggestions
    suggestions = indexes.FacetCharField()

    def get_model(self):
        return Product

    def index_queryset(self, using=None):
        """Used when the entire index for model is updated."""
        return self.get_model().objects.filter(timestamp__lte=timezone.now())

模型.py

class Product(models.Model):
    destination = models.CharField(max_length=255, default='')
    title = models.CharField(max_length=255, default='')
    slug = models.SlugField(unique=True, max_length=255)
    description = models.TextField(max_length=2047, default='')
    link = models.TextField(max_length=500, default='')

    ptags = TaggableManager()

    image = models.ImageField(max_length=500, default='images/zero-image-found.png')
    timestamp = models.DateTimeField(auto_now=True)

    def _ptags(self):
        return [t.name for t in self.ptags.all()]

    def get_absolute_url(self):
        return reverse('product',
                       kwargs={'slug': self.slug})

    def save(self, *args, **kwargs):
        if not self.id:
            self.slug = slugify(self.title)
        super(Product, self).save(*args, **kwargs)


    def __str__(self):
        return self.destination

最后,在我看来.py:

from haystack.generic_views import FacetedSearchView as BaseFacetedSearchView
from .forms import FacetedProductSearchForm
from haystack.query import SearchQuerySet


def autocomplete(request):
    sqs = SearchQuerySet().autocomplete(
        content_auto=request.GET.get('query',''))[:5]
    destinations = {result.destination for result in sqs}
    s = [{"value": dest, "data": dest} for dest in destinations]
    output = {'suggestions': s}
    return JsonResponse(output)


class FacetedSearchView(BaseFacetedSearchView):

    form_class = FacetedProductSearchForm
    facet_fields = ['ptags']
    template_name = 'search_result.html'
    paginate_by = 30
    context_object_name = 'object_list'

关于如何实现这一目标有什么想法吗?

python json elasticsearch django-haystack searchqueryset
1个回答
0
投票

我知道这已经很旧了,但是对于从谷歌到达这里的任何人来说,获得此功能的一种方法似乎是在模型中包含一个函数,该函数提供您的字段的“基本 ascii”版本(例如塞维利亚变成塞维利亚):

class Product(models.Model):
    destination = model.CharField()

    def ascii_destination(self):
        return strip_accents(self.destination)

正如这个答案中所建议的。然后将 ascii_name 字段添加到您的索引中。

© www.soinside.com 2019 - 2024. All rights reserved.