如何在AJAX调用上重新呈现django模板代码

时间:2016-09-27 14:43:41

标签: jquery ajax django django-pagination

我有一个视图,它将分页对象(在查询集上)发送到模板,我在模板中进一步呈现为表格。我要做的是点击模板上分页栏上的页码,它应该进行ajax调用以获取该页码的分页输出,并动态更新表的内容。

查看:

def accounts(request):
    #Including only necessary part
    accounts_list = Accounts.objects.all()
    paginator = Paginator(accounts_list, 25)
    page = request.GET.get('page')
    try:
        accounts = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        accounts = paginator.page(1)
    except EmptyPage:
        # If page is out of range, deliver last page of results.
        accounts = paginator.page(paginator.num_pages)

    context['accounts'] = accounts
    return render(request, template, context)

模板将其加载为:

{% if accounts %}
<table id="acc">
    <tr>
        <th>Field 1</th>
        ...
        <th>Field N</th>
    </tr>
    {% for item in accounts %}
    <tr> 
        <td>{{ item.field1 }}</td>
        ...<!-- Some complex logic with template tags too in here -->
        <td>{{ item.fieldN }}</td>
    </tr>
    {% endfor %}
</table>
{% endif %}

现在对于分页栏,我正在使用Bootpag's library,我可以将内容渲染为:

$('.pagination_top').bootpag({
   /*bootpag logic here */
}).on("page", function(event, num){
    //$.ajax loading here where I can update the table div with new output 
    //or make the table div "template code" reload without reloading page
}

很抱歉,我没有展示我在ajax部分上所做的大部分内容,因为我完全空白如何在不重新加载页面的情况下重新呈现新帐户的模板。

我能想到的唯一一个肮脏的解决方案是在视图中生成我的整个html,然后用新的html ajax更新表格div的html?

使用在不重新加载页面的情况下编写的模板渲染逻辑重新加载表格div的简单方法是什么?这可以通过使表格部分成为一个单独的模板并包含/扩展模板来实现吗?

请注意我不能使用在模板上获取所有数据然后使用某些jquery / js libaray的分页逻辑的方法,因为完整的数据相对非常大。

2 个答案:

答案 0 :(得分:3)

我解决了以下问题:

将表格部分作为模板table.html分隔为:

应用程序/ table.html:

{% if accounts %}
<table id="acc">
    <tr>
        <th>Field 1</th>
        ...
        <th>Field N</th>
    </tr>
    {% for item in accounts %}
    <tr> 
        <td>{{ item.field1 }}</td>
        ...<!-- Some complex logic with template tags too in here -->
        <td>{{ item.fieldN }}</td>
    </tr>
    {% endfor %}
</table>
{% endif %}

在主模板main.html中将其作为包含模板调用:

应用程序/ main.html中:

<div class="table-responsive">
    {% include 'app/table.html' %}
</div>

现在在我看来,如果请求是ajax请求,我添加了一行只呈现table.html

if request.is_ajax():
        return render(request, 'app/table.html', context)
#else
return render(request, 'app/main.html', context)

重新加载关于分页的表格:

$('.pagination_top').bootpag({
   /*bootpag logic here */
}).on("page", function(event, num){
    $(".table-responsive").html('').load(
        "{% url 'app:accounts' %}?page=" + num
    );
});

答案 1 :(得分:1)

如果您想依赖django模板,您应该重新加载页面并发送请求中的分页信息。这是通常所做的(例如在django-admin中)。它需要重新加载页面,但这就是为django模板制作的。

否则我会将整个渲染委托给客户端,并在django中只提供一个JSON视图。这样,django将提供一个模板,其中包含一些标记以及您最喜欢的js库,它负责进行AJAX调用并直接在其上呈现数据。

<强>更新

如果你真的需要这样做,你提到的方法是可能的。没有什么能阻止你渲染你的模板的一部分,外包在单独的文件中,并将已经呈现的HTML发送到你的客户端。

因此,您可以使用include template tag将表格模板移动到单独的文件中。 对于AJAX调用,您应该使用第二个视图,它只是呈现模板的表格部分。

这一切对我来说都是一种hacky,但它应该有效。