typeahead 的远程自动完成仅适用于唯一查询
remote autocomplete by typeahead works only on unique queries
我在使用 bloodhound 在两个字段(符号和名称)上设置 typeahead 时遇到问题。你可以在我的 DGI portfolio manager and autocomplete remote source here.
上试用 live 版本
Typeahead 有时有效,有时无效。
如果我输入 symbols,例如 "jnj"、"mcd"、"aapl",它会起作用。
但是,当我从 name 中键入字符串时,例如 "corporation" 和 "inc" 有大约 3000 个对象具有此名称,它不起作用。我怀疑这是因为它正在加载,因为 json 文件服务很快(在本地主机上不到 250 毫秒)。
首先,我认为符号工作正常并且名称被忽略。但是对于某些名称,我确实提前输入了正确的内容:例如 "apple" 和 "homestreet"。
我相信它只有在有 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 response:
[{"tokens": ["Johnson", "&", "Johnson"], "symbol": "JNJ", "name": "Johnson & Johnson"}]
不适用于 "sto":
json response:
[{"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."}]
是typeahead.js's bug。它应该在版本 0.11.2 中修复。
我在使用 bloodhound 在两个字段(符号和名称)上设置 typeahead 时遇到问题。你可以在我的 DGI portfolio manager and autocomplete remote source here.
上试用 live 版本
Typeahead 有时有效,有时无效。
如果我输入 symbols,例如 "jnj"、"mcd"、"aapl",它会起作用。
但是,当我从 name 中键入字符串时,例如 "corporation" 和 "inc" 有大约 3000 个对象具有此名称,它不起作用。我怀疑这是因为它正在加载,因为 json 文件服务很快(在本地主机上不到 250 毫秒)。
首先,我认为符号工作正常并且名称被忽略。但是对于某些名称,我确实提前输入了正确的内容:例如 "apple" 和 "homestreet"。
我相信它只有在有 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 response:
[{"tokens": ["Johnson", "&", "Johnson"], "symbol": "JNJ", "name": "Johnson & Johnson"}]
不适用于 "sto":
json response:
[{"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."}]
是typeahead.js's bug。它应该在版本 0.11.2 中修复。