【问题标题】:Django haystack autocomplete ajax (a href wrap into object)Django haystack 自动完成 ajax(href 包装到对象中)
【发布时间】:2015-05-02 17:23:51
【问题描述】:

我是 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>

谢谢

【问题讨论】:

    标签: jquery ajax django autocomplete


    【解决方案1】:

    Javascript 无法解析 django 模板标签,所以在这种情况下:

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

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


    根据您更新的代码,您只需要让服务器以某种方式生成指向您的项目的链接(可能对 django 对象使用get_absolute_url,这还有其他好处)并将其包含在返回的 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)
        }
      }
    

    【讨论】:

    • 感谢乐高...关于如何做到这一点的任何提示?我当前的视图代码是: def autocomplete(request): sqs = SearchQuerySet().autocomplete(content_auto=request.GET.get('q', ''))[:10]Suggestions = [result.username or result.title对于 sqs 中的结果] the_data = json.dumps({ 'results':Suggestions }) return HttpResponse(the_data, content_type='application/json')
    • 将其编辑到您的问题中,我可以稍后查看
    • 感谢您的帮助,但如果我按照您的建议更改代码,结果不会显示在自动完成中...您可以重新检查所有代码是否正确吗?
    • 我能得到的代码是一个指示,应该为您指明正确的方向。正如我所说,您需要编写一种生成 URL 的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多