下面我将详细讲解如何使用Django实现分页显示效果,包含两个例子。
环境与工具
- Python 3.x
- Django 3.x
安装分页插件
Django自带分页,但是功能相对简单,对于一些高级功能可能不够用,这时我们可以使用第三方分页插件:django-pagination,使用pip安装即可:
pip install django-pagination
分页的使用
第一个例子:简单分页
假设我们的网站需要显示一些文章,每页显示5篇,我们需要实现文章的分页。我们以Blog为例:
1. 首先,在Blog应用下的views.py文件中定义视图函数
from django.core.paginator import Paginator
from django.shortcuts import render
from .models import Blog
def blog_list(request):
all_blogs = Blog.objects.all()
paginator = Paginator(all_blogs, 5) # 每页显示5篇文章
page_number = request.GET.get('page')
page = paginator.get_page(page_number)
return render(request, 'blog_list.html', {'page': page})
定义了blog_list
函数后,可以访问模板'blog_list.html'来显示分页后的文章列表。
其中,all_blogs
是所有Blog对象组成的QuerySet。
django.core.paginator
模块中的Paginator类接收两个参数:需要分页的对象(一个QuerySet对象)和每页显示的数量。上面的分页方式每页显示5条文章。
request.GET.get('page')
用来获取GET请求的页面,如果没有获取到,则默认显示第一页。
paginator.get_page
用来获取指定页面的内容。
2. 然后,在Blog应用下的templates目录下新建模板文件blog_list.html
{% extends 'base.html' %}
{% block content %}
<h2>Blog List</h2>
{% for blog in page %}
<h3>{{ blog.title }}</h3>
<p>{{ blog.content }}</p>
{% empty %}
<p>No blogs.</p>
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if page.has_previous %}
<a href="?page=1">« first</a>
<a href="?page={{ page.previous_page_number }}">‹ previous</a>
{% endif %}
<span class="current-page">
Page {{ page.number }} of {{ page.paginator.num_pages }}.
</span>
{% if page.has_next %}
<a href="?page={{ page.next_page_number }}">next ›</a>
<a href="?page={{ page.paginator.num_pages }}">last »</a>
{% endif %}
</span>
</div>
{% endblock %}
在模板中,我们使用for循环遍历当前页的所有Blog对象,然后如果没有查询到任何Blog对象,则输出"No blogs."。
这个模板的重点是分页的代码,使用page.has_previous
、page.has_next
、page.previous_page_number
、page.next_page_number
和page.paginator.num_pages
来实现上一页、下一页、第一页、最后一页等功能。
page.has_previous
如果为True,表示当前页存在前一页面。page.has_next
如果为True,表示当前页存在后一页面。page.previous_page_number
表示前一页面的页码。page.next_page_number
表示后一页面的页码。page.paginator.num_pages
表示总的页面数。
最后,使用paginate对象的方法paginator.page_range
,可以得到当前分页的页码列表。
第二个例子:ajax异步分页
现在很多网站都喜欢用ajax实现异步分页,下面提供一种简单的方法。
1. 首先,在Blog应用下的views.py文件中定义视图函数
from django.shortcuts import render
from django.core.paginator import Paginator
from .models import Blog
def blog_list_ajax(request):
all_blogs = Blog.objects.all() # 查询所有Blog对象
paginator = Paginator(all_blogs, 5) # 每页显示5篇文章
try:
page = int(request.GET.get("page"))
except:
page = 1
# 对超过总页码数的页码进行处理
if page > paginator.num_pages:
page = paginator.num_pages
if page < 1:
page = 1
current_page = paginator.page(page)
return render(request, 'blog_list_ajax.html', {
'current_page': current_page,
'paginator': paginator,
'blogs': current_page.object_list
})
这里我们定义了blog_list_ajax
函数,用于返回ajax异步加载的分页数据。
在这个函数里,我们首先查询出所有Blog对象,并且使用paginator对象来分页,每页显示5篇文章。然后,我们通过GET请求的参数获取当前页码,如果没有获取到,则默认显示第一页。之后,我们对当前页码进行一些处理,如判断当前页码是否超出总页码数的范围,如果超出则指定为最后一页。
最后,我们传递三个参数给模板,current_page
是当前页码,paginator
是paginator对象,blogs
是当前页显示的Blog对象的列表。
2. 然后,在Blog应用下的templates目录下新建模板文件blog_list_ajax.html
{% extends 'base.html' %}
{% block content %}
<h2>Blog List AJAX</h2>
<div id="blog-list">
{% for blog in blogs %}
<h3>{{ blog.title }}</h3>
<p>{{ blog.content }}</p>
{% empty %}
<p>No blogs.</p>
{% endfor %}
</div>
{% if current_page.has_other_pages %}
<nav class="blog-pagination">
{% if current_page.has_previous %}
<input class="prev-page" type="button" value="Prev" data-url="?page={{ current_page.previous_page_number }}" />
{% endif %}
<span>
Page {{ current_page.number }} of {{ current_page.paginator.num_pages }}.
</span>
{% if current_page.has_next %}
<input class="next-page" type="button" value="Next" data-url="?page={{ current_page.next_page_number }}" />
{% endif %}
</nav>
{% endif %}
{% endblock %}
{% block js %}
<script>
$(document).ready(function() {
$('.blog-pagination input').click(function(event) {
var url = $(this).data('url');
$.get(url, function(html) {
$('#blog-list').html($(html).find('#blog-list').html());
})
});
});
</script>
{% endblock %}
在这个模板中,我们使用了jQuery来异步加载分页数据。首先,我们用一个id为blog-list的div来包裹所有Blog对象的列表。然后,在分页的代码中,我们使用了当前页的has_previous
和has_next
属性来判断是否存在前一页和后一页。如果存在,则给两个按钮添加data-url属性表示下一页或上一页。
最后,我们使用jQuery的get方法异步请求后端数据,获取新的HTML代码,然后将此代码的blog-list部分插入到我们的页面中(使用empty方法清空当前页之后插入新的分页内容)。
至此,我们已经讲解了使用Django实现分页显示效果的两个例子,详细讲解了如何安装和使用第三方分页插件django-pagination,并展示了两种使用分页插件的方法,一种是简单分页方式,一种是ajax异步分页方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django实现分页显示效果 - Python技术站