Django 实现分页功能
准备
-
新建项目、app
-
准备数据库
为了方便,直接用默认的sqlite了,目的是实现分页,写一个超级简单的模型就好。
模型
class Article(models.Model): title = models.CharField(max_length=100)视图
用于随便添加几条数据
def add_article(request): articles = [] for i in range(250): articles.append(Article(title='文章%d' % i)) Article.objects.bulk_create(articles) return HttpResponse('success')
分页
简单实现
可以直接利用Django内置的ListView做一个简单分页
视图
class ArticleView(ListView):
model = Article
template_name = 'list.html'
context_object_name = 'articles'
paginate_by = 10
ordering = '-id'
page_kwarg = 'page'
模板
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>文章列表</title>
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<ul>
{% for article in articles %}
<li>{{ article.title }}</li>
{% endfor %}
</ul>
<nav>
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="{% url 'list' %}?page={{ page_obj.previous_page_number }}">«</a>
</li>
{% endif %}
{% for page in paginator.page_range %}
{% if page == page_obj.number %}
<li class="page-item active">
<a class="page-link" href="{% url 'list' %}?page={{ page }}">{{ page }}</a>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="{% url 'list' %}?page={{ page }}">{{ page }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="{% url 'list' %}?page={{ page_obj.next_page_number }}">»</a>
</li>
{% endif %}
</ul>
</nav>
</body>
</html>
很容易就运行出来了,但是哪里怪怪的,这个分页也太长了吧。

想象中的分页:


改进
重写ListView的get_context_data方法,在上下文中增加一些“自己的东西”。
class ArticleView(ListView):
model = Article
template_name = 'articles.html'
context_object_name = 'articles'
paginate_by = 10
ordering = '-id'
page_kwarg = 'page'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context.update(self.get_pagination_data(paginator, page_obj))
return context
@staticmethod
def get_pagination_data(paginator, page_obj, around=2):
"""这个分页算法的核心部分,其实仔细看看也不难"""
current = page_obj.number # 当前页码
total = paginator.num_pages # 总共的页码
if current <= around + 3:
left_has_more = False
left_page_range = range(1, current)
else:
left_has_more = True
left_page_range = range(current - around, current)
if current >= total - around - 2:
right_has_more = False
right_page_range = range(current + 1, total + 1)
else:
right_has_more = True
right_page_range = range(current + 1, current + around + 1)
return {
'left_has_more': left_has_more,
'right_has_more': right_has_more,
'left_page_range': left_page_range,
'right_page_range': right_page_range
}
模板
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>文章列表</title>
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<ul>
{% for article in articles %}
<li>{{ article.title }}</li>
{% endfor %}
</ul>
<nav>
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="{% url 'list' %}?page={{ page_obj.previous_page_number }}">«</a>
</li>
{% endif %}
{% if left_has_more %}
<li class="page-item">
<a class="page-link" href="{% url 'list' %}?page=1">1</a>
</li>
<li class="page-item">
<a class="page-link" href="javascript: void(0);">...</a>
</li>
{% endif %}
{% for page in left_page_range %}
<li class="page-item">
<a class="page-link" href="{% url 'list' %}?page={{ page }}">{{ page }}</a>
</li>
{% endfor %}
<li class="page-item active">
<a class="page-link" href="javascript: void(0);">{{ page_obj.number }}</a>
</li>
{% for page in right_page_range %}
<li class="page-item">
<a class="page-link" href="{% url 'list' %}?page={{ page }}">{{ page }}</a>
</li>
{% endfor %}
{% if right_has_more %}
<li class="page-item">
<a class="page-link" href="javascript: void(0);">...</a>
</li>
<li class="page-item">
<a class="page-link" href="{% url 'list' %}?page={{ paginator.num_pages }}">{{ paginator.num_pages }}</a>
</li>
{% endif %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="{% url 'list' %}?page={{ page_obj.next_page_number }}">»</a>
</li>
{% endif %}
</ul>
</nav>
</body>
</html>
最终效果






浙公网安备 33010602011771号