【问题标题】:Using typeahead.js in Django project在 Django 项目中使用 typeahead.js
【发布时间】: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 来获取“源”列表,但我尝试过但无法做到。

【问题讨论】:

    标签: javascript jquery django twitter-bootstrap typeahead.js


    【解决方案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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-04
      • 1970-01-01
      • 2017-11-05
      • 2012-04-06
      • 2016-09-28
      • 2020-02-23
      • 1970-01-01
      • 2017-04-02
      相关资源
      最近更新 更多