使用CBV(ListView)使用ajax响应Django更新HTML片段

时间:2017-09-27 05:32:03

标签: python ajax django

所以我有一个主页,其中包含一个基本列表视图,其中包含我的数据库中的所有对象(如cbv .all()查询中所示)。我想要做的是包括一个搜索过滤器,因此我认为将它隔离到一个单独的" list.html"是一个好主意。片段,以便以后可以重复使用。目前,我有一个ajax调用,它将信息发送到cbv,返回是一个呈现给list.html的片段。但是,当我访问主页时,页面无法开始呈现。

非常感谢帮助或建议,再次感谢您。

urls.py

urlpatterns = [
url(r'^$', exp_view.DrugListView.as_view() , name = 'drug_list')]

这是我的CBV模板:

views.py

class DrugListView(ListView):
context_object_name = 'drugs'
model = Drug
template_name = 'expirations/drug_list.html'

def get(self, request):
    if self.request.is_ajax():
        text_to_search = self.request.GET.get('searchText')
        print(text_to_search)
        return render(request, "expirations/list.html", {'drug':Drug.objects.filter(name__contains = text_to_search).order_by('name')})
    else:
        return render(request, "expirations/list.html", {'drug':Drug.objects.all().order_by('name')})

这里是 的 drug_list.html

{% extends 'expirations/index.html' %}

{% block content %}

{% include 'expirations/list.html' %}

{% endblock %}
{% block javascript %}
<script>
$(document).ready(function(){
  var input = $("#searchText")
    input.keyup(function() {
    $.ajax({
      type: "GET",
      url: "{% url 'drug_list' %}",
      data: {'searchText' : input.val()},
      success: function(data){
        $("#list_view").load("expirations/list.html")
        }
    })
    });
})
</script>
{% endblock %}

这里是 list.html

{% for drug in drugs %}
    <div class = '.col-sm-12'>
        <ul class = 'list-group'>
            <li class = "list-group-item" >
              <span class = "badge">First Expiration: {{ drug.early_exp|date:"l M d Y" }}</span>
              <a href="{% url 'drug_detail' pk=drug.pk %}">{{ drug.name }}</a>
              {% regroup drug.expiration_dates.all by facility as facility_list %}
              {% for x in facility_list %}
              <span class="label label-info">{{ x.grouper }}</span>
              {% endfor %}
            </li>
        </ul>
    </div>
{% endfor %}

3 个答案:

答案 0 :(得分:0)

我认为它不会这样。对于Ajax调用和CBV,请查看example in the docs

然后你需要通过JS将新的,过滤后的数据(以html格式)返回到ajax调用和replace成功函数中的html。

答案 1 :(得分:0)

您误解了success回调中需要执行的操作。

该函数无法访问Django模板。但它不需要,因为Django已经在响应中发送了片段,该片段在data参数中可用。您只需将其插入现有页面即可。

为此,你需要一个容器;所以你应该修改你的drug_list.html,以便在include周围有一个div:

{% block content %}

<div id="list_contents">
  {% include 'expirations/list.html' %}
</div>

{% endblock %}

现在您的成功功能可以是:

  success: function(data) {
    $("#list_contents").html(data)
 }

答案 2 :(得分:0)

Daniel Roseman肯定帮助解决了这个难题,这里是更新的代码:

views.py :更新if / else语句以包含常规模板的默认列表视图。还添加了上下文名称'药物'而不是'药物'

class DrugListView(ListView):
    context_object_name = 'drugs'
    model = Drug
    template_name = 'expirations/drug_list.html'

    def get(self, request):
        if self.request.is_ajax():
            text_to_search = self.request.GET.get('searchText')
            print(text_to_search)
            return render(request, "expirations/list.html", {'drugs':Drug.objects.filter(name__contains = text_to_search).order_by('name')})
        else:
            return render(request, "expirations/drug_list.html", {'drugs':Drug.objects.all().order_by('name')})

drug_list.html :根据daniel的建议更改了成功回调函数加载HTML。

{% extends 'expirations/index.html' %}

{% block content %}
  <div id = 'list_view'>
  {% include 'expirations/list.html' %}
  </div>
{% endblock %}
{% block javascript %}
<script>
$(document).ready(function(){
  var input = $("#searchText")
    input.keyup(function() {
    $.ajax({
      type: "GET",
      url: "{% url 'drug_list' %}",
      data: {'searchText' : input.val()},
      success: function(data){
        $("#list_view").html(data)
        }
    })
    });
})
</script>
{% endblock %}