zoukankan      html  css  js  c++  java
  • 063.Python前端Django分页器


    Django的分页器

    1 前期准备

    创建一个数据库,用于存放数据

    mysql> create database pager default charset=utf8;

    mysql> use pager;

    setting注册

    复制代码
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'pager',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'USER': 'root',
            'PASSWORD': '123456',
        }
    }
    复制代码

    配置__init__

    import  pymysql
    pymysql.install_as_MySQLdb()

    模型数据models.py

    复制代码
    from django.db import models
    
    # Create your models here.
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5,decimal_places=2)
    复制代码

    执行数据迁移操作

    root@darren-virtual-machine:~/PycharmProjects/cbv_test# python3 manage.py makemigrations

    root@darren-virtual-machine:~/PycharmProjects/cbv_test# python3 manage.py migrate

    数据库

    mysql> desc app01_book;

     

    配置路由

    复制代码
    from django.urls import  path,re_path
    from app01 import views
    
    urlpatterns = [
        path('login_fbv/',views.login),
        path('login_cbv/', views.Login.as_view()),
        path('book_list/',views.Booklist.as_view()),
    ]
    复制代码

    views文件

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    class Booklist(View):
        def get(self,request):
            for i in range(1,101):
                Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
            Book.objects.create
            return render(request,"book_list.html")
    复制代码

    book_list.html

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    class Booklist(View):
        def get(self,request):
            for i in range(1,101):
                Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
            Book.objects.create
            return render(request,"book_list.html")
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/

    查看数据库

    mysql> select * from app01_book;

     

    这种方式比较慢

    方法二:

    mysql> delete from app01_book;

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    class Booklist(View):
        def get(self,request):
            temp_list = []
            for i in range(1,101):
                #Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
                temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
            Book.objects.bulk_create(temp_list)
            return render(request,"book_list.html")
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/

    mysql> select * from app01_book;

    复制代码
    +-----+----------+--------+
    | id  | title    | price  |
    +-----+----------+--------+
    | 101 | book_1   | 195.00 |
    | 102 | book_2   |  95.00 |
    | 103 | book_3   |  69.00 |
    | 104 | book_4   | 118.00 |
    | 105 | book_5   | 108.00 |
    | 106 | book_6   | 165.00 |
    ....略...
    | 199 | book_99  |  34.00 |
    | 200 | book_100 |  99.00 |
    +-----+----------+--------+
    复制代码

    已经插入数据,速度比较快,同时及时注释掉创建数据的内容

    显示书名和价格

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    class Booklist(View):
        def get(self,request):
            #temp_list = []
            #for i in range(1,101):
                #Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
            #    temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
            #Book.objects.bulk_create(temp_list)
            book_list = Book.objects.all()
            #把book_list传到模板层
            return render(request,"book_list.html",{
                "book_list":book_list,
            })
    复制代码

    book_list.html文件

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>图书列表</h3>
    <ul>
        {% for book in book_list %}
            <li>{{ book.title }}---价格---{{ book.price }}</li>
        {% endfor %}
    </ul>
    </body>
    </html>
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/

    已经显示到页面上,导入分页器

    2 分页器语法

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    class Booklist(View):
        def get(self,request):
            #temp_list = []
            #for i in range(1,101):
                #Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
            #    temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
            #Book.objects.bulk_create(temp_list)
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            paginator = Paginator(book_list, 10)
            print("count", paginator.count)  # 数据的总数
            print("num_pages", paginator.num_pages)  # 分页的总页数
            print("page_range", paginator.page_range)  # 页数的范围列表
    
            #把book_list传到模板层
            return render(request,"book_list.html",{
                "book_list":book_list,
            })
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/,调试输出

    count 100     #100条数据
    num_pages 10  #10页
    page_range range(1, 11)  #1-11
    [10/Apr/2020 14:36:42] "GET /app01/book_list/ HTTP/1.1" 200 4906

    显示每一页数据

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    class Booklist(View):
        def get(self,request):
            #temp_list = []
            #for i in range(1,101):
                #Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
            #    temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
            #Book.objects.bulk_create(temp_list)
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            paginator = Paginator(book_list, 10)
            #print("count", paginator.count)  # 数据的总数
            #print("num_pages", paginator.num_pages)  # 分页的总页数
            #print("page_range", paginator.page_range)  # 页数的范围列表
            page1 = paginator.get_page(1)
            for i in page1:
                print(i)
            #把book_list传到模板层
            return render(request,"book_list.html",{
                "book_list":book_list,
            })
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/,调试输出

    复制代码
    Book object (101)
    Book object (102)
    Book object (103)
    Book object (104)
    Book object (105)
    Book object (106)
    Book object (107)
    Book object (108)
    Book object (109)
    Book object (110)
    复制代码

    获取对象

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    class Booklist(View):
        def get(self,request):
            #temp_list = []
            #for i in range(1,101):
                #Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
            #    temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
            #Book.objects.bulk_create(temp_list)
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            paginator = Paginator(book_list, 10)
            #print("count", paginator.count)  # 数据的总数
            #print("num_pages", paginator.num_pages)  # 分页的总页数
            #print("page_range", paginator.page_range)  # 页数的范围列表
            page1 = paginator.get_page(1)
         page2 = paginator.get_page(2) #for i in page1: # print(i) print(page1.object_list) #把book_list传到模板层 return render(request,"book_list.html",{ "book_list":book_list, })
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/,调试输出,是query_set对象

    <QuerySet [<Book: Book object (101)>, <Book: Book object (102)>, <Book: Book object (103)>, <Book: Book object (104)>, <Book: Book object (105)>, <Book: Book object (106)>, <Book: Book object (107)>, <Book: Book object (108)>, <Book: Book object (109)>, <Book: Book object (110)>]>

    查看是否有上一页或者下一页

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    class Booklist(View):
        def get(self,request):
            #temp_list = []
            #for i in range(1,101):
                #Book.objects.create(title="book_%s" % i,price = random.randint(30,200))
            #    temp_list.append(Book(title="book_%s" % i,price = random.randint(30,200)))
            #Book.objects.bulk_create(temp_list)
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            paginator = Paginator(book_list, 10)
            #print("count", paginator.count)  # 数据的总数
            #print("num_pages", paginator.num_pages)  # 分页的总页数
            #print("page_range", paginator.page_range)  # 页数的范围列表
            #page1 = paginator.get_page(1)
            page2 = paginator.get_page(2)
            #for i in page1:
            #    print(i)
            #print(page1.object_list)
            print(page2.has_next())  # 是否有下一页
            print(page2.next_page_number())  # 下一页的页码
            print(page2.has_previous())  # 是否有上一页
            print(page2.previous_page_number())  # 上一页的页码
            #把book_list传到模板层
            return render(request,"book_list.html",{
                "book_list":book_list,
            })
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/,调试输出

    True
    3
    True
    1

    这两个报错

            # page=paginator.page(22)   # error:EmptyPage
            # page=paginator.page("z")   # error:PageNotAnInteger

    原因:

    进入get_page查看源码

     

    复制代码
        def get_page(self, number):
            """
            Return a valid page, even if the page argument isn't a number or isn't
            in range.
            """
            try:
                number = self.validate_number(number)    
            except PageNotAnInteger:
                number = 1     #非数字转为1
            except EmptyPage:
                number = self.num_pages   #空转为最大页数
            return self.page(number)
    复制代码

    使用get就不会报错

    views文件

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    class Booklist(View):
        def get(self,request):
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            paginator = Paginator(book_list, 10)
            #基本使用
            #获取当前页
            current_page = request.GET.get('page')
            #获取当前页数据,同时在html中循环
            page = paginator.get_page(current_page)
    
            #把book_list传到模板层
            return render(request,"book_list.html",{
                #"book_list":book_list,
                "page": page
            })
    复制代码

    html文件

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>图书列表</h3>
    <ul>
        {% for book in page %}
            <li>{{ book.title }}---价格---{{ book.price }}</li>
        {% endfor %}
    </ul>
    </body>
    </html>
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/,为空,显示第一页

     

    访问http://127.0.0.1:8000/app01/book_list/?page=4,显示第四页

    3 添加分页器

    使用bootstrap做分页器显示

    静态文件配置

    root@darren-virtual-machine:~/PycharmProjects/cbv_test# mkdir statics

    root@darren-virtual-machine:~/PycharmProjects/cbv_test# mkdir statics/css statics/js statics/images statics/plugins

    root@darren-virtual-machine:~/PycharmProjects/cbv_test# ll statics/plugins/

    drwxr-xr-x 5 root root 4096 4月  11 08:38 bootstrap-3.4.1-dist/

    注册静态文件

    STATIC_URL = '/static/'
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,"statics"),
    ]

    html添加样式

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
    </head>
    <body>
    <h3>图书列表</h3>
    <ul>
        {% for book in page %}
            <li>{{ book.title }}---价格---{{ book.price }}</li>
        {% endfor %}
    </ul>
    <nav aria-label="Page navigation">
      <ul class="pagination">
        <li>
          <a href="#" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
        </li>
        <li><a href="#">1</a></li>
        <li><a href="#">2</a></li>
        <li><a href="#">3</a></li>
        <li><a href="#">4</a></li>
        <li><a href="#">5</a></li>
        <li>
          <a href="#" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
      </ul>
    </nav>
    </body>
    </html>
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/如下

    下面应该可以显示所有的页面,使用一个for循环

    views,把页数传递到html

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    class Booklist(View):
        def get(self,request):
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            paginator = Paginator(book_list, 10)
            #基本使用
            #获取当前页
            current_page = request.GET.get('page')
            #获取当前页数据,同时在html中循环
            page = paginator.get_page(current_page)
    
            #把book_list传到模板层
            return render(request,"book_list.html",{
                #"book_list":book_list,
                "page": page,
                "paginator" :paginator
            })
    复制代码

    html文件

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
    </head>
    <body>
    <h3>图书列表</h3>
    <ul>
        {% for book in page %}
            <li>{{ book.title }}---价格---{{ book.price }}</li>
        {% endfor %}
    </ul>
    <nav aria-label="Page navigation">
      <ul class="pagination">
        <li>
          <a href="#" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
        </li>
          {% for num in paginator.page_range  %}
            <li><a href="?page={{ num }}">{{ num }}</a></li>
          {% endfor %}
        <li>
          <a href="#" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
      </ul>
    </nav>
    </body>
    </html>
    复制代码

    访问显示

    4 分页器添加上一页和下一页代码

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
    </head>
    <body>
    <h3>图书列表</h3>
    <ul>
        {% for book in page %}
            <li>{{ book.title }}---价格---{{ book.price }}</li>
        {% endfor %}
    </ul>
    <nav aria-label="Page navigation">
      <ul class="pagination">
      {% if page.has_previous %}
          <li>
          <a href="?page={{ page.previous_page_number }}" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
          </li>
          {% else %}
          <li class="disabled">
          <a href="javascript:void(0)" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
    
      {% endif %}
    
          {% for num in paginator.page_range  %}
            <li><a href="?page={{ num }}">{{ num }}</a></li>
          {% endfor %}
        {% if page.has_next %}
          <li>
          <a href="?page={{ page.next_page_number }}" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
          {% else %}
          <li class="disabled">
          <a href="javascript:void(0)" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
    
      {% endif %}
    
      </ul>
    </nav>
    </body>
    </html>
    复制代码

    访问效果

    5 分页器添加首页和尾页

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
    </head>
    <body>
    <h3>图书列表</h3>
    <ul>
        {% for book in page %}
            <li>{{ book.title }}---价格---{{ book.price }}</li>
        {% endfor %}
    </ul>
    <nav aria-label="Page navigation">
      <ul class="pagination">
      <li><a href="?page=1">首页</a></li>
      {% if page.has_previous %}
          <li>
          <a href="?page={{ page.previous_page_number }}" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
          </li>
          {% else %}
          <li class="disabled">
          <a href="javascript:void(0)" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
    
      {% endif %}
    
          {% for num in paginator.page_range  %}
            <li><a href="?page={{ num }}">{{ num }}</a></li>
          {% endfor %}
        {% if page.has_next %}
          <li>
          <a href="?page={{ page.next_page_number }}" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
          {% else %}
          <li class="disabled">
          <a href="javascript:void(0)" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
    
      {% endif %}
        <li><a href="?page={{ paginator.num_pages }}">尾页</a></li>
      </ul>
    </nav>
    </body>
    </html>
    复制代码

    访问效果

    6 分页器添加当前页标记

    views文件传递参数

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    class Booklist(View):
        def get(self,request):
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            paginator = Paginator(book_list, 10)
            #基本使用
            #获取当前页,在后面需要进行对当前页标记,和num比较,需要转换成int类型
            current_page = int(request.GET.get('page',1))
            #获取当前页数据,同时在html中循环
            page = paginator.get_page(current_page)
    
            #把book_list传到模板层
            return render(request,"book_list.html",{
                #"book_list":book_list,
                "page": page,
                "paginator" :paginator,
                "current_page": current_page
            })
    复制代码

    html文件配置

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
    </head>
    <body>
    <h3>图书列表</h3>
    <ul>
        {% for book in page %}
            <li>{{ book.title }}---价格---{{ book.price }}</li>
        {% endfor %}
    </ul>
    <nav aria-label="Page navigation">
      <ul class="pagination">
      <li><a href="?page=1">首页</a></li>
      {% if page.has_previous %}
          <li>
          <a href="?page={{ page.previous_page_number }}" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
          </li>
          {% else %}
          <li class="disabled">
          <a href="javascript:void(0)" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
    
      {% endif %}
    
          {% for num in paginator.page_range  %}
              {% if num == current_page %}
                  <li class="active"><a href="?page={{ num }}">{{ num }}</a></li>
              {% else %}
                  <li><a href="?page={{ num }}">{{ num }}</a></li>
              {% endif %}
          {% endfor %}
        {% if page.has_next %}
          <li>
          <a href="?page={{ page.next_page_number }}" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
          {% else %}
          <li class="disabled">
          <a href="javascript:void(0)" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
    
      {% endif %}
        <li><a href="?page={{ paginator.num_pages }}">尾页</a></li>
      </ul>
    </nav>
    </body>
    </html>
    复制代码

    当有50页显示时,例如将每页显示2

     paginator = Paginator(book_list, 2)

    显示如下

    7 显示改进

    views文件

    复制代码
    from django.shortcuts import render,redirect,HttpResponse
    from django.views import  View
    import  time
    from django.utils.decorators import method_decorator
    
    # Create your views here.
    
    def timer(func):
        def inner(request,*args,**kwargs):
            start_time = time.time()
            time.sleep(2)
            rep = func(request,*args,**kwargs)
            end_time = time.time()
            print (end_time-start_time)
            return rep
        return inner
    
    #FBV
    @timer
    def login(request):
        if request.method == "GET":
            return render(request,"login.html")
        else:
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request,"login.html")
    
    
    #CBV
    @method_decorator(timer,name="get")
    class Login(View):
        #@method_decorator(timer)
        def dispatch(self, request, *args, **kwargs):
            obj = super().dispatch(request,*args,**kwargs)
            return obj     #这里必须返回,否则Httpresponse错误
        #@method_decorator(timer)
        def get(self,request):
            return render(request, "login.html")
        def post(self,request):
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request, "login.html")
    
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    class Booklist(View):
        def get(self,request):
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            paginator = Paginator(book_list, 2)
            #基本使用
            #获取当前页,在后面需要进行对当前页标记,和num比较,需要转换成int类型
            current_page = int(request.GET.get('page',1))
            #获取当前页数据,同时在html中循环
            page = paginator.get_page(current_page)
            # 我们按照页面显示11个页码为例。
            # 如果总页码大于11
            if paginator.num_pages > 11:
                if current_page - 5 < 1:  # 当前页小于中间页码时
                    page_range = range(1, 12)
                elif current_page + 5 > paginator.num_pages:  # 当前页大于中间页码时
                    page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
                else:
                    page_range = range(current_page - 5, current_page + 6)
            else:
                page_range = paginator.page_range
            #把book_list传到模板层
            return render(request,"book_list.html",{
                #"book_list":book_list,
                "page": page,
                "paginator" :paginator,
                "current_page": current_page,
                "page_range": page_range
            })
    复制代码

    html

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
    </head>
    <body>
    <h3>图书列表</h3>
    <ul>
        {% for book in page %}
            <li>{{ book.title }}---价格---{{ book.price }}</li>
        {% endfor %}
    </ul>
    <nav aria-label="Page navigation">
      <ul class="pagination">
      <li><a href="?page=1">首页</a></li>
      {% if page.has_previous %}
          <li>
          <a href="?page={{ page.previous_page_number }}" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
          </li>
          {% else %}
          <li class="disabled">
          <a href="javascript:void(0)" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
    
      {% endif %}
    
          {% for num in page_range  %}
              {% if num == current_page %}
                  <li class="active"><a href="?page={{ num }}">{{ num }}</a></li>
              {% else %}
                  <li><a href="?page={{ num }}">{{ num }}</a></li>
              {% endif %}
          {% endfor %}
        {% if page.has_next %}
          <li>
          <a href="?page={{ page.next_page_number }}" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
          {% else %}
          <li class="disabled">
          <a href="javascript:void(0)" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
    
      {% endif %}
        <li><a href="?page={{ paginator.num_pages }}">尾页</a></li>
      </ul>
    </nav>
    </body>
    </html>
    复制代码

    效果如下,前面

     

    中间

    最后

     

    保证每页显示11个 

    8 自定制分页器

    root@darren-virtual-machine:~/PycharmProjects/cbv_test# vim app01/utils.py 

    复制代码
    class Paginator:
        def __init__(self, current_page, all_count, per_page=10, max_page_num=11):
            """
            封装分页相关数据
            :param current_page:  当前页码
            :param all_count:  数据库中的数据总条数
            :param per_page:   每个页面显示的数据条数
            :param max_page_num:  最多显示的页码个数
            :param num_pages:  通过总条数/每个页面显示的条数,求出总页数
            """
            try:
                current_page = int(current_page)
            except Exception as e:
                current_page = 1
            if current_page < 1:
                current_page = 1
            self.current_page = current_page
            self.all_count = all_count
            self.per_page = per_page
    
            # 计算总页数
            num_pages, temp = divmod(all_count, per_page)
            if temp:
                num_pages += 1
            self.num_pages = num_pages
    
            self.max_page_num = max_page_num  # 11
            self.page_count_half = int((self.max_page_num - 1) / 2)  # 5
            """
            self.num_pages=100
            per_page=8
    
            current_page =1     [0:8]
            current_page =2     [8:16]
            current_page =3     [16:24]
                                [(current_page-1)*per_page:current_page*per_page ]
    
            """
    
        @property
        def start(self):
            return (self.current_page - 1) * self.per_page
    
        @property
        def end(self):
            return self.current_page * self.per_page
    
        def page_html(self):
            # 如果总页数小于self.max_page_num(最多显示的页码个数)
            if self.num_pages <= self.max_page_num:
                page_start = 1
                page_end = self.num_pages + 1
            else:
                # 如果当前页码<=页面上最多显示11/2个页码时
                if self.current_page <= self.page_count_half:
                    page_start = 1
                    page_end = self.max_page_num + 1
                # 如果当前页码+最多显示11/2 大于 总页数时
                elif self.current_page + self.page_count_half > self.num_pages:
                    page_start = self.num_pages - self.max_page_num + 1
                    page_end = self.num_pages + 1
                else:
                    page_start = self.current_page - self.page_count_half
                    page_end = self.current_page + self.page_count_half + 1
    
            page_html_list = []
    
            # 首页
            first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?page=1">首页</a></li>'
            page_html_list.append(first_page)
    
            # 上一页
            if self.current_page <= 1:
                prev_page = '<li class="disabled"><a href="javascript:void(0);">上一页</a></li>'
            else:
                prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1, )
            page_html_list.append(prev_page)
    
            # 显示页码
            for i in range(page_start, page_end):
                if self.current_page == i:
                    temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
                else:
                    temp = '<li><a href="?page=%s">%s</a></li>' % (i, i)
                page_html_list.append(temp)
    
            # 下一页
            if self.current_page >= self.num_pages:
                next_page = '<li class="disabled"><a href="javascript:void(0);">下一页</a></li>'
            else:
                next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1)
            page_html_list.append(next_page)
    
            # 尾页
            last_page = '<li><a href="?page=%s">尾页</a></li></ul></nav>' % self.num_pages
            page_html_list.append(last_page)
    
            return "".join(page_html_list)
    复制代码

    视图调用

    复制代码
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    #为了避免重复,取得别名
    from app01.utils import Paginator as MyPaginator
    class Booklist(View):
        def get(self,request):
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            #paginator = Paginator(book_list, 2)
            #基本使用
            #获取当前页,在后面需要进行对当前页标记,和num比较,需要转换成int类型
            current_page = int(request.GET.get('page',1))
            #获取当前页数据,同时在html中循环
            #page = paginator.get_page(current_page)
            # 我们按照页面显示11个页码为例。
            # 如果总页码大于11
            #if paginator.num_pages > 11:
            #    if current_page - 5 < 1:  # 当前页小于中间页码时
            #        page_range = range(1, 12)
            #    elif current_page + 5 > paginator.num_pages:  # 当前页大于中间页码时
            #        page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
            #    else:
            #        page_range = range(current_page - 5, current_page + 6)
            #else:
            #    page_range = paginator.page_range
            paginator = MyPaginator(current_page, book_list.count(), 8, 11)
            book_list = book_list[paginator.start:paginator.end]
            #把book_list传到模板层
            #return render(request,"book_list.html",{
            return render(request, "book_list1.html", {
                "book_list":book_list,
                #"page": page,
                "paginator" :paginator,
                "current_page": current_page,
                #"page_range": page_range,
                #"book_list":book_list,
            })
    复制代码

    book_list1.html

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
         <link rel="stylesheet" href="/static/plugins/bootstrap-3.4.1-dist/css/bootstrap.css">
    </head>
    <body>
    <h3>书籍列表!!!</h3>
    
    <ul>
        {% for book in book_list %}
            <li>{{ book.title }}---价格---{{ book.price }}</li>
        {% endfor %}
    </ul>
    {{ paginator.page_html|safe }}
    </body>
    </html>
    复制代码

    结果

    9 带参数分页器调用 

    如果需要携带参数

    utils文件

    复制代码
    class Paginator:
        def __init__(self, request, current_page, all_count, per_page=10, max_page_num=11):
            """
            封装分页相关数据
            :param current_page:  当前页码
            :param all_count:  数据库中的数据总条数
            :param per_page:   每个页面显示的数据条数
            :param max_page_num:  最多显示的页码个数
            :param num_pages:  通过总条数/每个页面显示的条数,求出总页数
            """
            try:
                current_page = int(current_page)
            except Exception as e:
                current_page = 1
            if current_page < 1:
                current_page = 1
            self.current_page = current_page
            self.all_count = all_count
            self.per_page = per_page
    
            # 计算总页数
            num_pages, temp = divmod(all_count, per_page)
            if temp:
                num_pages += 1
            self.num_pages = num_pages
    
            self.max_page_num = max_page_num  # 11
            self.page_count_half = int((self.max_page_num - 1) / 2)  # 5
    
            import copy
            self.url_args = copy.deepcopy(request.GET)
            print(self.url_args.urlencode())
            """
            self.num_pages=100
            per_page=8
    
            current_page =1     [0:8]
            current_page =2     [8:16]
            current_page =3     [16:24]
                                [(current_page-1)*per_page:current_page*per_page ]
    
            """
    
        @property
        def start(self):
            return (self.current_page - 1) * self.per_page
    
        @property
        def end(self):
            return self.current_page * self.per_page
    
        def page_html(self):
            # 如果总页数小于self.max_page_num(最多显示的页码个数)
            if self.num_pages <= self.max_page_num:
                page_start = 1
                page_end = self.num_pages + 1
            else:
                # 如果当前页码<=页面上最多显示11/2个页码时
                if self.current_page <= self.page_count_half:
                    page_start = 1
                    page_end = self.max_page_num + 1
                # 如果当前页码+最多显示11/2 大于 总页数时
                elif self.current_page + self.page_count_half > self.num_pages:
                    page_start = self.num_pages - self.max_page_num + 1
                    page_end = self.num_pages + 1
                else:
                    page_start = self.current_page - self.page_count_half
                    page_end = self.current_page + self.page_count_half + 1
    
            page_html_list = []
    
            # 首页
            self.url_args['page'] = 1
            #first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?page=1">首页</a></li>'
            first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?page=%s">首页</a></li>' % self.url_args.urlencode()
            page_html_list.append(first_page)
    
            # 上一页
            if self.current_page <= 1:
                prev_page = '<li class="disabled"><a href="javascript:void(0);">上一页</a></li>'
            else:
                self.url_args['page'] = self.current_page - 1
                #prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1, )
                prev_page = '<li><a href="?%s">上一页</a></li>' % self.url_args.urlencode()
            page_html_list.append(prev_page)
    
            # 显示页码
            for i in range(page_start, page_end):
                self.url_args['page'] = i
                if self.current_page == i:
                    #temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i)
                    temp = '<li class="active"><a href="?%s">%s</a></li>' % (self.url_args.urlencode(), i)
                else:
                    #temp = '<li><a href="?page=%s">%s</a></li>' % (i, i)
                    temp = '<li><a href="?%s">%s</a></li>' % (self.url_args.urlencode(), i)
                page_html_list.append(temp)
    
            # 下一页
            if self.current_page >= self.num_pages:
                next_page = '<li class="disabled"><a href="javascript:void(0);">下一页</a></li>'
            else:
                self.url_args['page'] = self.current_page + 1
                #next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1)
                next_page = '<li><a href="?%s">下一页</a></li>' % self.url_args.urlencode()
            page_html_list.append(next_page)
    
            # 尾页
            self.url_args['page'] = self.num_pages
            #last_page = '<li><a href="?page=%s">尾页</a></li></ul></nav>' % self.num_pages
            last_page = '<li><a href="?%s">尾页</a></li></ul></nav>' % self.url_args.urlencode()
            page_html_list.append(last_page)
    
            return "".join(page_html_list)
    复制代码

    视图文件

    复制代码
    from django.shortcuts import render,redirect,HttpResponse
    from django.views import  View
    import  time
    from django.utils.decorators import method_decorator
    
    # Create your views here.
    
    def timer(func):
        def inner(request,*args,**kwargs):
            start_time = time.time()
            time.sleep(2)
            rep = func(request,*args,**kwargs)
            end_time = time.time()
            print (end_time-start_time)
            return rep
        return inner
    
    #FBV
    @timer
    def login(request):
        if request.method == "GET":
            return render(request,"login.html")
        else:
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request,"login.html")
    
    
    #CBV
    @method_decorator(timer,name="get")
    class Login(View):
        #@method_decorator(timer)
        def dispatch(self, request, *args, **kwargs):
            obj = super().dispatch(request,*args,**kwargs)
            return obj     #这里必须返回,否则Httpresponse错误
        #@method_decorator(timer)
        def get(self,request):
            return render(request, "login.html")
        def post(self,request):
            username = request.POST.get("username")
            password = request.POST.get("password")
            if username == "joy" and password == "123456":
                return HttpResponse("login success...")
            else:
                return render(request, "login.html")
    
    #分页器
    from app01.models import Book
    #from app01 import models
    import random
    from django.core.paginator import Paginator
    #为了避免重复,取得别名
    from app01.utils import Paginator as MyPaginator
    class Booklist(View):
        def get(self,request):
            book_list = Book.objects.all()
            #分页器的基本语法
            # 实例化分页器对象
            #paginator = Paginator(book_list, 2)
            #基本使用
            #获取当前页,在后面需要进行对当前页标记,和num比较,需要转换成int类型
            current_page = int(request.GET.get('page',1))
            #获取当前页数据,同时在html中循环
            #page = paginator.get_page(current_page)
            # 我们按照页面显示11个页码为例。
            # 如果总页码大于11
            #if paginator.num_pages > 11:
            #    if current_page - 5 < 1:  # 当前页小于中间页码时
            #        page_range = range(1, 12)
            #    elif current_page + 5 > paginator.num_pages:  # 当前页大于中间页码时
            #        page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
            #    else:
            #        page_range = range(current_page - 5, current_page + 6)
            #else:
            #    page_range = paginator.page_range
            paginator = MyPaginator(request,current_page, book_list.count(), 8, 11)
            book_list = book_list[paginator.start:paginator.end]
            #把book_list传到模板层
            #return render(request,"book_list.html",{
            return render(request, "book_list1.html", {
                "book_list":book_list,
                #"page": page,
                "paginator" :paginator,
                "current_page": current_page,
                #"page_range": page_range,
                #"book_list":book_list,
            })
    复制代码

    访问http://127.0.0.1:8000/app01/book_list/?page=10&name=joy&password=123结果如下

    当代有参数时,把鼠标放在不分页器上,最下面可以显示到后面页带的有参数


    参考文档:https://www.cnblogs.com/Michael--chen/p/10965465.html 

    老男孩教育视频:https://www.oldboyedu.com/

    学习记录,小白一枚
  • 相关阅读:
    javascript定义函数后立即执行(IIFE)
    工作流选型专项,Camunda or flowable or?
    Excel中的xlsm宏密码怎么破解
    《生命是什么》总结
    《麦肯锡教我的思考武器》总结
    《作为意志和表象的世界》总结
    Go语言如何将json时间格式化为dateime格式
    《少有人走的路》总结
    《时间简史》总结
    架构的常规分类及复用重点
  • 原文地址:https://www.cnblogs.com/wangsirde0428/p/14322939.html
Copyright © 2011-2022 走看看