Django 中设置分页页码,只显示当前页以及左右两页

设置后的效果如下:

  • Django 给我们提供了分页的功能:`Paginator`和`Page`类都是用来做分页的。他们在Django中的路径为:`from django.core.paginator import Page, Paginator`
  • 先简单解释一下他们的属性和方法:
  •  
    # Paginator常用属性和方法
    1. `count`: 总共有多少条数据。
    2. `num_pages`: 总共有多少页。
    3. `page_range`:页面的区间。比如有三页,那么就是`range(1,4)`。
    
    
    # Page常用属性和方法:
    1. `has_next`: 是否还有下一页。
    2. `has_previous`: 是否还有上一页。
    3. `next_page_number`: 下一页的页码。
    4. `previous_page_number`: 上一页的页码。
    5. `number`: 当前页。
    6. `start_index`: 当前页的第一条数据的索引值。
    7. `end_index`: 当前页的最后一条数据的索引值。
    

      

  •  article_list.html,这里我使用了bootscrip的组件样式:
  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>
        <ul>
            {% for article in articles %}
                <li>{{ article.title }}</li>
            {% endfor %}
        </ul>
    
        <nav aria-label="Page navigation">
          <ul class="pagination">
            {% if page_obj.has_previous %}
                <li><a href="{% url 'front:article_list' %}?page={{ page_obj.previous_page_number }}">上一页</a></li>
            {% else %}
                <li class="disabled"><a href="javascript:void(0);">上一页</a></li>
            {% endif %}
    
            {% if left_has_more %}
                <li><a href="{% url 'front:article_list' %}?page=1">1</a></li>
                <li><a href="javascript:void(0);">...</a></li>
            {% endif %}
    
            {# 左边的页码 #}
            {% for left_page in left_pages %}
                <li><a href="{% url 'front:article_list' %}?page={{ left_page }}">{{ left_page }}</a></li>
            {% endfor %}
            
            {# 中间的页码 #}
            <li><a href="{% url 'front:article_list' %}?page={{ current_page }}">{{ current_page }}</a></li>
            {# 右边的页码 #}
            {% for right_page in right_pages %}
                <li><a href="{% url 'front:article_list' %}?page={{ right_page }}">{{ right_page }}</a></li>
            {% endfor %}
    
            {% if right_has_more %}
                <li><a href="javascript:void(0);">...</a></li>
                <li><a href="{% url 'front:article_list' %}?page={{ paginator.num_pages }}">{{ paginator.num_pages }}</a></li>
            {% endif %}
    
          {% if page_obj.has_next %}
                <li><a href="{% url 'front:article_list' %}?page={{ page_obj.next_page_number }}">下一页</a></li>
            {% else %}
                <li class="disabled"><a href="javascript:void(0);">下一页</a></li>
            {% endif %}
          </ul>
        </nav>
    </body>
    </html>
    

      原理基本上是将页码分成三部分,第一部分是上一页和第一页,第二部分是当前所在页前两页和后两页(共计五页),第三部分是下一页和最后一页。

  •  视图函数:views.py
  •  
    class ArticleListView(ListView):
        model = Article
        template_name = 'article_list.html'
        context_object_name = 'articles'
        paginate_by = 10
        ordering = 'create_time'
    
        def get_context_data(self,  **kwargs):
            context = super(ArticleListView, self).get_context_data(**kwargs)
           
            paginator_data = self.get_pagination_data(paginator, page_obj)
            context.update(paginator_data) # 将当前字典的kv更新到context字典中。
            return context
      
    # 这里来负责跳转的页码处理 def get_pagination_data(self, paginator, page_obj, around_count=2): # arount_count=2表示从当前页前推两页,后推两页 current_page = page_obj.number num_page = paginator.num_pages left_has_more = False # 左边还有没有未显示的页码 right_has_more = False      # 判断当前页是不是比4小,比如当前页是第二页,他就不能存在 0.1.2.3.4这种情况。 if current_page <= around_count + 2: left_page = range(1, current_page) else: left_has_more = True left_page = range(current_page-around_count, current_page) if current_page >= num_page-around_count-1: right_page = range(current_page+1, num_page+1) else: right_has_more = True right_page = range(current_page+1, current_page+3) return { 'left_pages': left_page, 'right_pages': right_page, 'current_page': current_page, 'left_has_more': left_has_more, 'right_has_more': right_has_more, }

      这里定义了一个ArticleListView类,此类继承自ListView,用来处理请求等问题。

  •  front.urls.py,处理url跳转
  •  
    from django.urls import path
    from . import views
    
    app_name = 'front'
    urlpatterns = [
        path('add/', views.add_article, name='add'),
        path('list/', views.ArticleListView.as_view(), name='article_list')
    ]
    

      这里我把这次的跳转放到了front app中,可以直接放到项目的urls.py中。

  •  
  •  基本上就是这样,如果看不懂可以看一下我的整个项目,写的很乱,很多高级视图学习的时候的练习代码都堆在这里:https://github.com/longbigbeard/Python_Web/tree/master/Django%E7%BB%83%E4%B9%A0/views_gaoji
  •   
  •  
  •  
  •  以上。

原文地址:https://www.cnblogs.com/longbigbeard/p/10188328.html