在Django项目中使用typeahead.js
我有一个带电影数据库的django项目,希望我的搜索框能够简单地实现typeahead.js给我的自动完成function。 我正在使用它,因为它具有模板function,因为它非常适合我正在使用的Bootstrap样式。
urls.py
url(r'^get_movie/$', views.get_movie, name = 'get_movie')
views.py
def get_movie(request): results = [] q = request.GET['q'] movies = Movie.objects.filter(title__icontains = q) results = [ {movie.id: movie.name} for movie in movies ] data = json.dumps(results) return HttpResponse(data, content_type = 'application/json')
HTML搜索框
显然我包含了jQuery,Bootstrap和typeahead.js。
除了实现typeahead.js的javascript之外,上面是所有必需的代码
这是来自官方网站的一个例子,但我不知道我需要应用哪些修改才能从我的数据库中动态获取结果并在自动完成列表中显示它们:
$('.typeahead').typeahead(null, { name: 'best-pictures', display: 'value', source: bestPictures, templates: { empty: [ '{{value}} – {{year}}') } });
' ].join('\n'), suggestion: Handlebars.compile('
提示:我很确定我需要使用Ajax来获取“源”列表但是已经尝试过并且无法设法执行此操作。
我建议使用“远程”版本。 试试这个:
urls.py:
url(r'^get_movie/$', SearchListView.as_view(), name='get_movie'), url(r'^ajaxsearch/$', views.search_ajax, name='search_ajax')
views.py:
from django.db.models import Q from django.views.generic.list import ListView class SearchListView(ListView): model = Movie template_name = 'some_template.html' def get_context_data(self, *args, **kwargs): context = super(SearchListView, self).get_context_data(*args, **kwargs) context['query'] = self.request.GET.get('q') return context def get_queryset(self, *args, **kwargs): movie_qs = super(SearchListView, self).get_queryset(*args, **kwargs) query = self.request.GET.get('q') if query: user_qs = self.model.objects.filter( Q(title__icontains=query) ) return movie_qs @require_http_methods(['GET']) def search_ajax(request): q = request.GET.get('q') data = {} if q: titles = Movie.objects.filter(title__icontains=q) data = [{'title': title} for title in titles] return JsonResponse(data, safe=False)
搜索框:
JavaScript的:
var titlesDisplay = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title'), queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { url: "{% url 'search_ajax' %}", replace: function(url, query) { return url + "?q=" + query; } } }); $('#remote .typeahead').typeahead({ minLength: 1, highlight: true}, {name: 'titles-display', display: 'title', source: titlesDisplay, });
我们最终使用了朋友给我们的解决方案,效果很好: