У меня проблема с настройкой typehead с помощью Bloodhound в двух полях - символ и имя. Вы можете попробовать живую версию в моем менеджере портфолио DGI и использовать автозаполнение из удаленного источника здесь.
Упреждающий ввод иногда работает, а иногда нет.
Если я набираю символы< /strong>, такие как "jnj", "mcd", "aapl", это работает.
Однако, когда я набираю строку из названия, например "corporation" и "inc", у которых есть около 3000 объектов с это имя, оно не работает. Я сомневаюсь, что это потому, что он загружается, поскольку файл json обслуживается быстро (менее 250 мс на локальном хосте).
Во-первых, я думал, что символы работают правильно, а имена игнорируются. Но я получаю правильный ввод для некоторых имен: например, «яблоко» и «домовая улица».
Я считаю, что это работает, только если есть 1 или 2 результата. Но я не понимаю, файл json всегда выдает максимум 5 результатов.
Вот мои коды:
views.py для автозаполнения URL:
from haystack.query import SearchQuerySet
import json
def autocomplete(request):
if request.GET.get('q', '') == '':
array = []
else:
sqs = SearchQuerySet().models(Stock)
sqs_symbol = sqs.filter(symbol_auto=request.GET.get('q', ''))
sqs_name = sqs.filter(name_auto=request.GET.get('q', ''))
sqs_result = sqs_symbol | sqs_name
array = []
print sqs_result.count()
for result in sqs_result[:5]:
data = {"symbol": str(result.symbol),
"name": str(result.name),
"tokens": str(result.name).split()
}
array.insert(0, data)
print array
return HttpResponse(json.dumps(array), content_type='application/json')
Я добавил печать, чтобы знать, когда она не работает. файл search_indexes.py:
from haystack import indexes
from stocks.models import Stock
class StockIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
symbol = indexes.CharField(model_attr='symbol')
name = indexes.CharField(model_attr='name')
# We add this for autocomplete.
symbol_auto = indexes.EdgeNgramField(model_attr='symbol')
name_auto = indexes.EdgeNgramField(model_attr='name')
def get_model(self):
return Stock
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.all()
И в моем html-файле шаблона:
<script type="text/javascript">
$(function(){
var stocks = new Bloodhound({
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.tokens);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
limit: 5,
remote: {
url: "/search/autocomplete/",
replace: function(url, query) {
return url + "?q=" + query;
},
filter: function(stocks) {
return $.map(stocks, function(data) {
return {
tokens: data.tokens,
symbol: data.symbol,
name: data.name
}
});
}
}
});
stocks.initialize();
$('.typeahead').typeahead(null, {
name: 'stocks',
displayKey: 'name',
minLength: 1, // send AJAX request only after user type in at least X characters
source: stocks.ttAdapter(),
templates: {
suggestion: function(data){
return '<p>' + data.name + ' (<strong>' + data.symbol + '</strong>)</p>';
}
}
}).on('typeahead:selected', function (obj, stock) {
window.location.href = "/stocks/detail/" + stock.symbol;
});
});
</script>
РЕДАКТИРОВАТЬ: Некоторые примеры
Json ответ:
[{"tokens": ["Johnson", "&", "Johnson"], "symbol": "JNJ", "name": "Johnson & Johnson"}]
Не работает для "sto":
ответ json:
[{"tokens": ["QKL", "Stores,", "Inc."], "symbol": "QKLS", "name": "QKL Stores, Inc."}, {"tokens": ["SPDR", "DJ", "STOXX", "50"], "symbol": "FEU", "name": "SPDR DJ STOXX 50 "}, {"tokens": ["Statoil", "ASA"], "symbol": "STO", "name": "Statoil ASA"}, {"tokens": ["STORE", "Capital", "Corporation"], "symbol": "STOR", "name": "STORE Capital Corporation"}, {"tokens": ["StoneMor", "Partners", "L.P."], "symbol": "STON", "name": "StoneMor Partners L.P."}]