2017-09-27 42 views
0

因此,我有一个基础列表视图,它包含我的数据库中的所有对象(如cbv .all()查询所示)。我想要做的是包含一个搜索过滤器,因此我认为将它隔离为一个单独的“list.html”片段是一个好主意,以便稍后使其可重用。目前,我有一个将信息发送给cbv的ajax调用,返回的是对list.html片段的呈现。但是,当我访问主页时,页面不会被渲染。使用CBV(ListView)更新ajax响应Django的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 %} 

回答

0

您误解了您在回拨success时需要做的事情。

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

为此,您需要一个容器;所以你应该修改drug_list.html以便有是围绕一个div包括:

{% block content %} 

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

{% endblock %} 

,现在你的成功的功能可以是:

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

这绝对有帮助。是否有指导来了解ajax调用的成功函数的范围? – user3866172

0

我不认为它会以这种方式工作。对于Ajax调用和CBV请看example in the docs

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

0

丹尼尔·罗斯曼一定帮助解决这一难题,这里是更新的代码:

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:改变成功的回调函数加载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 %}