如何在Django类基础的通用ListViews中使用分页?
如何在Django的基于类的通用ListViews中使用分页?
这个问题的出现是因为有两种方法可以实现分页,第一种方法简单,只需要设置类字段paginate_by
,不需要对get_context_data
方法做任何处理。第二种方法稍微复杂一些,但我们可以更好地理解分页,并自定义复杂的分页或多个分页。
首先,我们需要重写View
的get_context_data
方法。通过传递page_keys
和pages
参数,我们可以遍历列表并避免硬编码。
接下来,我们需要自定义子模板。我们定义一些变量,以便我们可以遍历分页列表。
最后,我们需要自定义外部模板。在这个模板中,我们遍历data
列表,并在每个分页数据块中包含分页模板。
具体代码请参考上文。
在这段代码中,我们定义了一个名为FileExam
的模型类,它有四个属性:myfile、date、teacher_name和status。然后,我们创建了一个名为FileExamListView
的类,它继承自Django的ListView
类,并指定了模型为FileExam
。这个类的作用是将FileExam
模型的数据传递给模板,以便在页面上显示。我们还定义了paginate_by
属性,指定每页显示的数据数量为10。
在get_context_data
方法中,我们首先获取所有的FileExam
对象,并使用Django的分页器类Paginator
将数据分页。然后,我们通过self.request.GET.get('page')
获取当前页的页码。接下来,我们使用try-except
语句处理异常情况。如果页码不是一个整数,则会抛出PageNotAnInteger
异常,我们将当前页设置为第一页。如果页码超出范围,则会抛出EmptyPage
异常,我们将当前页设置为最后一页。最后,将分页后的数据存储在上下文中,传递给模板。
在模板中,我们首先展示了普通的内容列表,使用{% for exam in list_exams %}
遍历每个FileExam
对象,并将其属性显示在表格中。接下来,我们展示了分页部分,使用{% if is_paginated %}
判断是否需要显示分页。如果需要分页,则使用page_obj
对象获取当前页的页码和总页数,并根据是否有上一页和下一页显示相应的链接。如果不需要分页,则显示提示信息。
最后,在urls.py
中将FileExamListView
视图函数与file-exam-view
命名空间绑定,以便在其他地方可以通过命名空间引用该视图函数。
通过测试发现,我们不能像你一样拦截PageNotAnInteger
异常,因为如果我们通过GET
参数传递一个非整数值,会在ListView
类的paginate_queryset
方法中引发ValueError
异常。希望这样清楚明白。
问题的出现原因是,用户想要了解如何在Django的类视图中使用分页功能。这是因为在传统的函数视图中很容易找到这个功能,但在新的类视图中却不太清楚。
解决方法是,在视图中设置paginate_by
变量即可激活分页功能。具体代码如下:
import models from django.views.generic import ListView class CarListView(ListView): model = models.Car template_name = 'app/car_list.html' context_object_name = "car_list" paginate_by = 10
在模板文件car_list.html
中,可以通过以下代码添加分页部分:
{% if car_list %}
<table id="cars">
{% for car in car_list %}
<tr>
<td>{{ car.model }}</td>
<td>{{ car.year }}</td>
<td><a href="/car/{{ car.id }}/" class="see_detail">detail</a></td>
</tr>
{% endfor %}
</table>
{# .... **Now the pagination section** .... #}
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
<a href="/cars?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="page-current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="/cars?page={{ page_obj.next_page_number }}">next</a>
{% endif %}
</span>
</div>
{% endif %}
{% else %}
<h3>My Cars</h3>
<p>No cars found!!! :(</p>
{% endif %}
其中,is_paginated
、page_obj
和paginator
是可用的上下文变量。
此外,还可以在URL模式中使用page
参数来指定要显示的页码,例如:?page=n
。
至于如何将模板与"car_list"对象关联起来,可以在urls.py文件中直接使用ListView.as_view()
方法,如下所示:
url(r'^cars/$', ListView.as_view( model=Car, paginate_by=10 )),
还可以通过使用jQuery和Ajax来实现Django的分页功能,具体方法可以参考相关教程。