在 Django 项目中使用 typeahead.js

Posted

技术标签:

【中文标题】在 Django 项目中使用 typeahead.js【英文标题】:Using typeahead.js in Django project 【发布时间】:2015-12-04 13:36:13 【问题描述】:

我有一个带有电影数据库的 django 项目,并且希望我的搜索框能够简单地实现 typeahead.js 给我的自动完成功能。我之所以使用它是因为它的模板功能,并且因为它非常适合我用于样式的 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 搜索框

<input id="searchBox" type="text" class="form-control input-lg typeahead" placeholder="Search a movie..." name="q"></input>

显然我已经包含了 jQuery、Bootstrap 和 typeahead.js。

上面是除了实现 typeahead.js 的 javascript 之外的所有必要代码

这是来自官方网站的示例,但我不知道我需要应用哪些修改才能从我的数据库中动态获取结果并将它们显示在自动完成列表中:

<script type="text/javascript">
  $('.typeahead').typeahead(null, 
    name: 'best-pictures',
    display: 'value',
    source: bestPictures,
    templates: 
      empty: [
        '<div class="empty-message">',
          'unable to find any Best Picture winners that match the current query',
        '</div>'
      ].join('\n'),
      suggestion: Handlebars.compile('<div><strong>value</strong> – year</div>')
    
  );
</script>

提示:我很确定我需要使用 Ajax 来获取“源”列表,但我尝试过但无法做到。

【问题讨论】:

【参考方案1】:

我建议使用“远程”版本。试试这个:

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)

搜索框:

<div id="remote" class="twitter-typeahead">
    <input type="text" class="form-control input-lg typeahead tt-input" name="q" placeholder="Search a movie..." />
</div>

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,
);

【讨论】:

我已经发布了一个朋友向我们提出的问题的解决方案。甚至没有机会实施您的解决方案,但非常感谢您的帮助。 :)【参考方案2】:

我们最终使用了朋友给我们的这个解决方案,并且效果很好:

<script type="text/javascript">
  $(document).ready(function()
    var queryMovies = new Bloodhound(
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        limit: 20,
        rateLimitWait: 800,
        remote: url:'/get_movie/?q=%QUERY', wildcard: '%QUERY'
    );

    queryMovies.initialize();

    $('#remote .typeahead').typeahead(
        hint: true,
        highlight: true,
        minLength: 2,
    ,
    
        name: 'queryMovies',
        display: 'value',
        source: queryMovies.ttAdapter(),
        templates: 
            empty: [
            '<div class="empty-message">',
            'No hay resultados con la consulta',
            '</div>'
            ].join('\n'),
            suggestion: function(data) 
              var url = "% url 'movie' '00000' %"
              url = url.replace('00000', data.id);
              return '<div><p><a href="' + url + '">' + data.title + '</a></p></div>';
            
        
    );
  );
</script>

【讨论】:

以上是关于在 Django 项目中使用 typeahead.js的主要内容,如果未能解决你的问题,请参考以下文章

使用 Django / Python 为 Typeahead / Bloodhound 提供远程 JSON 数据

当源是来自 Django 的字典时,使用预取 + 远程的 Typeahead Bloodhound 自动完成

带有 django 的 Json 响应列表

Twitter bootstrap typeahead custom keypress ENTER 功能

在 Angular 2 中使用 typeahead.js

如何在flutter中将数据从firestore传递给Typeahead