django分页

方法一:使用pure_pagination进行分页

1. pure_pagination介绍

pure_pagination基于并且兼容django原生的pagination模块。

2. 安装pure_pagination

pip install django-pure-pagination

3. 配置

  • 添加 pure_pagination 到 INSTALLED_APPS
INSTALLED_APPS = (
    ...
    'pure_pagination',
)

A few settings can be set within settings.py

PAGINATION_SETTINGS = {
    'PAGE_RANGE_DISPLAYED': 10,
    'MARGIN_PAGES_DISPLAYED': 2,
    'SHOW_FIRST_PAGE_WHEN_INVALID': True,
}

4. 代码

  • 视图函数
from pure_pagination import Paginator, EmptyPage, PageNotAnInteger
class IndexView(View):
    def get(self, request):
        # 文章列表
        article_list = Article.objects.filter()
        # 分页数据
        try:
            page = int(request.GET.get('page', 1))  # 页码
            paginator = Paginator(article_list, 10, request=request)  # 获取有多少页
            article_list = paginator.page(page)  # 获取指定页的数据
        except Exception as e:
            return HttpResponseRedirect('/')
       
        return render(request, 'index.html', {
            'article_list': article_list
        })
  • 模板
<ul class="pagination">
 {# 上一页 #}
 {% if article_list.has_previous %}
    <li class="waves-effect"><a href="?page={{ article_list.previous_page_number.querystring }}"><i class="material-icons">chevron_left</i></a></li>
{% else %}
    <li class="disabled"><a href="#!"><i class="material-icons">chevron_left</i></a></li>
{% endif %}
{% for page in article_list.pages %}
     {% if page %}
         {% ifequal page article_list.number %}
              {# 当前页页 #}
              <li class="active"><a>{{ page }}</a></li>
         {% else %}
              {# 指定页 #}
              <li class="waves-effect"><a href="?{{ page.querystring }}">{{ page }}</a></li>
         {% endifequal %}
     {% else %}
         <li class="waves-effect"><a href="#">...</a></li>
     {% endif %}
{% endfor %}
{# 下一页 #}
{% if article_list.has_next %}
      <li class="waves-effect"><a href="?page={{ article_list.next_page_number.querystring }}"><i class="material-icons">chevron_right</i></a></li>
{% else %}
      <li class="disabled"><a href="#!"><i class="material-icons">chevron_right</i></a></li>
{% endif %}

方法二:使用django原生的分页方法

使用原生的分页方法要想实现一个比较好的结果需要使用templatetags,有点复杂,下面我们一点一点来

1. 首先建立模板标签

app/
    templatetags/
        __init__.py
        paginate_tags.py

2. 编码

  • 视图函数
def question_index(request):
    article_list = Article.objects
    context = {
        'article_list': article_list,
    }
    return render(request, 'app/index.html', context)
  • paginate_tags
from django import template
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
register = template.Library()
// 这是定义模板标签要用到的
@register.simple_tag(takes_context=True)
def paginate(context, object_list, page_count):
    // context是Context 对象,object_list是你要分页的对象,page_count表示每页的数量
    left = 3
    right = 3
    // 获取分页对象
    paginator = Paginator(object_list, page_count)
    // 从请求中获取页码号
    page = context['request'].GET.get('page')
   
    try:
        object_list = paginator.page(page) # 根据页码号获取数据页码对象
        context['current_page'] = int(page) # 将当前页码号封装进context中
        // 获取页码列表
        // pages = paginator.page_range
        pages = get_left(context['current_page'], left, paginator.num_pages) + get_right(context['current_page'], right,                                                                                  paginator.num_pages)
    except PageNotAnInteger:
        object_list = paginator.page(1) # 获取首页数据页码对象
        context['current_page'] = 1
        // pages = paginator.page_range
        pages = get_right(context['current_page'], right, paginator.num_pages)
    except EmptyPage:
        // 用户传递的是一个空值,则把最后一页返回给他
        object_list = paginator.page(paginator.num_pages)
       // num_pages为总分页数
        context['currten_page'] = paginator.num_pages
        // pages = paginator.page_range
        pages = get_left(context['current_page'], left, paginator.num_pages)
    
    context['questions'] = object_list
    context['pages'] = pages  # 页码列表
    context['last_page'] = paginator.num_pages
    context['first_page'] = 1
    // 用于判断是否加入省略号
    
    try:
        context['pages_first'] = pages[0]
        context['pages_last'] = pages[-1] + 1
    except IndexError:
        context['pages_first'] = 1
        context['pages_last'] = 2
    return ''
def get_left(current_page, left, num_pages):
    """
    辅助函数,获取当前页码的值得左边两个页码值,要注意一些细节,比如不够两个那么最左取到2
    ,为了方便处理,包含当前页码值,比如当前页码值为5,那么pages = [3,4,5]
    """
    if current_page == 1:
        return []
    elif current_page == num_pages:
        l = [i - 1 for i in range(current_page, current_page - left, -1) if i - 1 > 1]
        l.sort()
        return l
    l = [i for i in range(current_page, current_page - left, -1) if i > 1]
    l.sort()
    return l
def get_right(current_page, right, num_pages):
    """
    辅助函数,获取当前页码的值得右边两个页码值,要注意一些细节,
    比如不够两个那么最右取到最大页码值。不包含当前页码值。比如当前页码值为5,那么pages = [6,7]
    """
    if current_page == num_pages:
        return []
    return [i + 1 for i in range(current_page, current_page + right - 1) if i < num_pages - 1]
  • 模板
<ul class="pagination">
    {# 判断是否还有上一页,确定是否激活上一页按钮 #}
    {% if questions.has_previous %}
        <li class="waves-effect"><a href="?page={{ questions.previous_page_number }}"><i class="material-icons">chevron_left</i></a></li>
    {% else %}
        <li class="disabled"><a href="#!"><i class="material-icons">chevron_left</i></a></li>
    {% endif %}

    { # 永远显示第一页 #}
    {% if first_page == current_page %}
        <li class="active"><a>1</a></li>
    {% else %}
        <li class="waves-effect"><a href="?page=1">1</a></li>
    {% endif %}

    {# 2以前的页码号要被显示成省略号 #}
    {% if pages_first > 2 %}
        <li class="waves-effect"><a href="#">...</a></li>
    {% endif %}

    {% for page in pages %}
        {% if page == current_page %}
            <li class="active"><a>{{ page }}</a></li>
        {% else %}
            <li class="waves-effect"><a href="?page={{ page }}">{{ page }}</a></li>
        {% endif %}
    {% endfor %}

    {# pages最后一个值+1的值小于最大页码号,说明有页码号需要被省略号替换 #}
    {% if pages_last < last_page %}
        <li class="waves-effect"><a href="#">...</a></li>
    {% endif %}
    
    {# 永远显示最后一页的页码号,如果只有一页则前面已经显示了1就不用再显示了 #}
    {% if last_page != 1 %}
        {% if last_page == current_page %}
            <li class="active"><a>{{ last_page }}</a></li>
        {% else %}
            <li class="waves-effect"><a href="?page={{ last_page }}">{{ last_page }}</a></li>
        {% endif %}
    {% endif %}

    {# 判断是否还有下一页,确定是否激活下一页按钮 #}
    {% if questions.has_next %}
        <li class="waves-effect"><a href="?page={{ questions.next_page_number }}"><i class="material-icons">chevron_right</i></a></li>
    {% else %}
        <li class="disabled"><a href="#!"><i class="material-icons">chevron_right</i></a></li>
    {% endif %}
</ul>

3. 使用

{% load paginate_tags %}
{% paginate article_list 3 %}   # 对应模板标签中的函数paginate(context, object_list, page_count),context是默认传入的,article_list代表object_list,3代表每页的数量
{% for article in article_list %}
    <section class="post">
        <h1>{{ article.title }}</h1>
        <p>{{ article.content }}</p>
        ...
    </section>
{% include 'pagination.html' %}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容

  • 我们先在 shell 中演示分页器的用法: 分页器示例 现在我们在 view 中使用分页器: 浏览器打开:http...
    SingleDiego阅读 1,612评论 2 3
  • 成果: 代码:在之后的步骤中在相信说明吧 步骤: 1.这个mongoengine需要pip安装的pip insta...
    泠泠七弦客阅读 4,056评论 2 0
  • Django中已经实现了很多功能,基本上只要我们需要的功能,都能够找到相应的包。要在Django中实现分页显示,只...
    leyu阅读 543评论 0 2
  • 我们要实现如下样子的分页界面 在不借助于第三方Django APP的情况下,仅仅使用Django框架提供的分页(P...
    Maslino阅读 1,872评论 0 4
  • 林逸维初见牧琪是在上选修课的教室里。 上课的铃声刚刚响过,教授正欲翻开书本授课。“嘭”一声,她几乎...
    里力阅读 467评论 0 0