强制django-autocomplete = light首先返回“最佳”匹配

时间:2015-11-02 06:28:52

标签: python django django-autocomplete-light

我使用django-autocomplete-light字段搜索了一长串项目,其中自动填充定义如下:

class OccupationAutocomplete(autocomplete_light.AutocompleteModelBase):
    model = models.Occupation
    search_fields=['title',]

有些职位名称按字母顺序排列在列表中,例如:

  

“老师”

来自其他“不太理想的头衔”,如:

  

“农业教师”,“建筑教师”,“建筑老师”等......

我想要的是“最佳”匹配,无论是最接近还是仅匹配从搜索文本开始,所以如果有人搜索“教学”,他们会得到“老师”,因为它从同一个开始字母,然后是其他不太准确的匹配。

我尝试使用首选订单设置search_fields

    search_fields=['^title','title',]

但对autocomplete code的分析表明,在返回之前,这些术语都被包含在一个查询中。

我如何以更合适的方式订购此列​​表?

1 个答案:

答案 0 :(得分:0)

最后我不得不实施一个新课程,这只是按照“首选权重”的顺序接受一个字典列表。然后根据该结果返回结果。

class OrderedAutocomplete(autocomplete_light.AutocompleteModelBase):
    ordered_search_fields = []

    def choices_for_request(self):
        """
        Return a queryset based on :py:attr:`choices` using options
        :py:attr:`split_words`, :py:attr:`search_fields` and
        :py:attr:`limit_choices`.
        """
        assert self.choices is not None, 'choices should be a queryset'
        q = self.request.GET.get('q', '')
        exclude = self.request.GET.getlist('exclude')

        base_split_words = self.split_words

        _choices = []
        for weight,opt in enumerate(self.ordered_search_fields):
            if len(_choices) >= self.limit_choices:
                break

            search_fields = opt['search_fields']
            self.split_words = opt['split_words'] or base_split_words

            conditions = self._choices_for_request_conditions(q,
                    search_fields)
            choices = self.order_choices(self.choices.filter(conditions).exclude(pk__in=exclude))
            if choices.count():
                _choices += list(choices)[0:self.limit_choices]

        return _choices[0:self.limit_choices]

然后可以使用以下方法对其进行实例化。

class OccupationAutocomplete(OrderedAutocomplete):
    model = models.Occupation

    ordered_search_fields = [
        {'search_fields': ['^title'], 'split_words':False},
        {'search_fields': ['title'], 'split_words':True},
        ]
autocomplete_light.register(OccupationAutocomplete)