Django haystack自动完成ajax(一个href包装成对象)

时间:2015-03-02 11:15:43

标签: jquery ajax django autocomplete

我是ajax和jQuery的新手,我希望在我的搜索中使用自动完成功能。我已经按照官方的Haystack教程进行自动完成(here),我可以正确显示结果。现在我希望显示的结果包含指向正确页面的链接,但我不知道该怎么做。我试图将{{ result.object.get_absolute_url }}包裹起来(与我在显示没有自动填充的搜索结果时使用的相同):

 var base_elem = $('<div class="result-wrapper"><a href="{{ result.object.get_absolute_url }}" class="ac-result"></a></div>')

但它不起作用。

有人可以展示并解释我应该如何在结果中包装url上下文?显然,在我的结果中包含链接的关键不在于Javascript,而是在服务器端构造URL并将其传递回结果。

的观点:

def autocomplete(request):
    sqs = SearchQuerySet().autocomplete(content_auto=request.GET.get('q', ''))[:10]
    suggestions = [result.username or result.title for result in sqs]
    the_data = json.dumps({
        'results': suggestions
    })
    return HttpResponse(the_data, content_type='application/json')

使用Javascript:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script type="text/javascript">
    // In a perfect world, this would be its own library file that got included
    // on the page and only the ``$(document).ready(...)`` below would be present.
    // But this is an example.
    var Autocomplete = function(options) {
      this.form_selector = options.form_selector
      this.url = options.url || '/search/autocomplete/'
      this.delay = parseInt(options.delay || 300)
      this.minimum_length = parseInt(options.minimum_length || 3)
      this.form_elem = null
      this.query_box = null
    }

    Autocomplete.prototype.setup = function() {
      var self = this

      this.form_elem = $(this.form_selector)
      this.query_box = this.form_elem.find('input[name=q]')

      // Watch the input box.
      this.query_box.on('keyup', function() {
        var query = self.query_box.val()

        if(query.length < self.minimum_length) {
          return false
        }

        self.fetch(query)
      })

      // On selecting a result, populate the search field.
      this.form_elem.on('click', '.ac-result', function(ev) {
        self.query_box.val($(this).text())
        $('.ac-results').remove()
        return false
      })
    }

    Autocomplete.prototype.fetch = function(query) {
      var self = this

      $.ajax({
        url: this.url
      , data: {
          'q': query
        }
      , success: function(data) {
          self.show_results(data)
        }
      })
    }

    Autocomplete.prototype.show_results = function(data) {
      // Remove any existing results.
      $('.ac-results').remove()

      var results = data.results || []
      var results_wrapper = $('<div class="ac-results"></div>')
      var base_elem = $('<div class="result-wrapper"><a href="{{ result.object.get_absolute_url }}" class="ac-result"></a></div>')

      if(results.length > 0) {
        for(var res_offset in results) {
          var elem = base_elem.clone()
          // Don't use .html(...) here, as you open yourself to XSS.
          // Really, you should use some form of templating.
          elem.find('.ac-result').text(results[res_offset])
          results_wrapper.append(elem)
        }
      }
      else {
        var elem = base_elem.clone()
        elem.text("No results found.")
        results_wrapper.append(elem)
      }

      this.query_box.after(results_wrapper)
    }

    $(document).ready(function() {
      window.autocomplete = new Autocomplete({
        form_selector: '.autocomplete-me'
      })
      window.autocomplete.setup()
    })
  </script>

感谢

1 个答案:

答案 0 :(得分:0)

Javascript无法解析django模板标签,所以在这个例子中:

<a href="{{ result.object.get_absolute_url }}" class="ac-result">

href字面意思是“{{ result.object.get_absolute_url }}”。您需要做的是在服务器端构建网址,并在致电results时将其传回/search/autocomplete/数据。


根据您更新的代码,您只需让服务器生成一个指向您的项目的链接(可能使用get_absolute_url用于django对象,这有其他好处)并在返回的json中包含该链接。

def autocomplete(request):
    sqs = SearchQuerySet().autocomplete(content_auto=request.GET.get('q', ''))[:10]
    suggestions = [  {'text':result.username or result.title,
                      'url':generate_url(result), }
                    for result in sqs
                  ]
    the_data = json.dumps({
        'results': suggestions
    })
    return HttpResponse(the_data, content_type='application/json')

然后相应地更新Autocomplete.prototype.show_results中的循环:

  var base_elem = $('<div class="result-wrapper"><a href="" class="ac-result"></a></div>')

  if(results.length > 0) {
    for(var res_offset in results) {
      var elem = base_elem.clone()
      // Don't use .html(...) here, as you open yourself to XSS.
      // Really, you should use some form of templating.
      elem.find('.ac-result').text(results[res_offset].text)
      elem.find('.ac-result').attr("href",results[res_offset].url)

      results_wrapper.append(elem)
    }
  }