zoukankan      html  css  js  c++  java
  • Django框架之ORM的相关操作之分页(六)

    分页是每个项目必不可少要写的一个功能,该篇文章就将记录一下使用ORM写分页的过程。

    假设我们的数据库里面需要显示一些数据,而这个表中的数据大约有几千条数据,那么我们不可能将所有的数据都显示出来,那么就需要使用分页来显示一部分数据,使用页数来进行翻页。在下面这个过程,我以一个demo的形式进行叙述。

    1.要想有许多数据,就要先创建一个存储数据的表,下面就使用模型类创建一个表。

    class TeacherTest(models.Model):
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=20)

    可以看到,这个表创建成功后有两个字段,第一个字段是id,第二个字段是name。

    2.分页可以说分为两大部分,第一部分就是考虑显示部分数据在界面上,第二部分就是考虑页码如何写。如果想象不出是什么样子,可以参考一下博客园的分页,如下图:

    首先考虑第一部分:如何显示部分数据在前端上,而不是显示表中所有的数据。这种情况下,我们会考虑使用切片的知识,比如:字符串str1="abcdefg"想要获取到abc怎么办呢,就使用切片,str2=str1[0:3]这样,就可以获取到了abc这个字符串。同样我们可以查询出所有的数据,然后通过切片的方法只获取到第几条到第几条数据,这样的话就可以显示出部分的数据了。

    我们定义一下,每页显示5条数据,那么使用orm显示第一页的数据就应该是:TeacherTest.objects.all()[0:5]。根据这个规律展开以下分析:

    显示数据      页数  切片  切片分析

    第1条-第5条数据       1     [0:5]          [(1-1)*5:1*5]

    第6条-第10条数据     2          [5:10]        [(2-1)*5:2*5]

    第11条-第15条数据   3          [10:15]      [(3-1)*5:3*5]

    ......

    第m条-第n条数据         j          [m-1:n]    [(j-1)*5:j*5]

    通过上面的分析,我们知道了页数与显示数据的切片的关系了,那么我们就可以解决了一个显示的问题。

    orm显示数据的语句就是:TeacherTest.objects.all()[(页码-1)*5:页码*5]

    点击页码按钮通过url传递参数,后端获取传递的页码数就可以显示对应的数据了。

    3.通过上面分析已经解决了显示问题,那么接下来就要显示分页了。要想知道分页,首先要知道的就是有多少条数据,然后根据计算这些数据需要多少页来显示数据。

    获取总数据量:TeacherTest.objects.count()

    假设表中的数据量是26条数据,那么可以分6页,最后一页显示1条数据;数据量是27条,也是分6页,最后一页显示2条数据。所有我们可以先计算出每页显示5条数据的页数,然后再计算是否还有不足5条数据,如果还有不足5条数据需要显示,那么就再计算出每页显示5条数据的页数加上1页,就得出总页数了。

    伪代码如下:

    data_count=Teacher.objects.count()
    # 满足每页5条数据的页数
    page_five=data_count//5
    # 计算是否有余数
    page=data_count%5
    
    if page==0:
        # 总页数
        page_num=page_five
    else:
        # 总页数
        page_num=page_five+1

    也可以使用divmod(a,b)函数来计算页数,如果不了解这个内置函数的话,可以通过网上查询来获悉这个函数的用法。

    最后我们计算出了页码总数,就需要在前端显示分页的页码,通过我们点击给前端传递参数。如果将页数传递到前端的话,前端没有range可以让我们使用来遍历,显示每个页码,我们只能在后端做好后,将页码传递到前端。这里我使用的是html在后端拼接,然后传递到前端。下面可以参考具体的代码来学习:

    后端代码:

    def show_page(request):
        if request.method=="GET":
            current_page=request.GET.get("page") # 获取跳转的页数
            current_page=int(current_page)
            show_num=5 # 显示条数
            """
            1-5条  [0:5]     1  [(1-1)*5:1*5]
            6-10条 [5:10]    2  [(2-1)*5:2*5]
            11-15条[10:15]   3  [(3-1)*5:3*5]
            m-n条  [m-1:n]   h  [(m-1)*5:n*5]
            """
            start_data=(current_page-1)*show_num # 从第几条数据显示
            end_data=current_page*show_num           # 显示到第几条技术
    
            """
            显示页数
            """
            data_count=models.TeacherTest.objects.count() # 数据的总数量
            m,n=divmod(data_count,show_num)
    
           
            page_list=[]
            if n==0:
                page_count=m
                for p in range(1,page_count+1):
                    page='<li><a href="/app05/page/?page={0}">{0}</a></li>'.format(p)
                    page_list.append(page)
            else:
                page_count=m+1
                for p in range(1,page_count+1):
                    page = '<li><a href="/app05/page/?page={0}">{0}</a></li>'.format(p)
                    page_list.append(page)
    
            show_data=models.TeacherTest.objects.all()[start_data:end_data]
            return render(request,"page.html",{"allteacher":show_data,"pagecount":page_count,"page_list":page_list})

    前端代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <!-- Optional theme -->
        <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    </head>
    <body>
    <table class="table-bordered" border="1" width="300">
        {% for teacher in allteacher %}
            <tr>
            <td>{{ teacher.id }}</td>
            <td>{{ teacher.name }}</td>
            </tr>
        {% endfor %}
        
    </table>
    <nav aria-label="Page navigation">
      <ul class="pagination">
        <li>
          <a href="#" aria-label="Previous">
            <span aria-hidden="true">&laquo;</span>
          </a>
        </li>
          {% for page in page_list %}
              {{ page|safe }}
          {% endfor %}
        <li>
          <a href="#" aria-label="Next">
            <span aria-hidden="true">&raquo;</span>
          </a>
        </li>
      </ul>
    </nav>
    </body>
    </html>

    ==============================================================================================================

    此时分页就基本上写完了,但是我们在使用的时候会发现一个问题,就是如果有300条数据的时候,页数就会有60页,此时分页的页码就会全部显示到界面上,那样的话就显示不好看了。所以就要显示分页的长度了。

    以下代码就是更新后的代码

    def show_page(request):
        if request.method=="GET":
            current_page=request.GET.get("page") # 获取跳转的页数
            current_page=int(current_page)
            show_num=5 # 显示条数
            """
            1-5条  [0:5]     1  [(1-1)*5:1*5]
            6-10条 [5:10]    2  [(2-1)*5:2*5]
            11-15条[10:15]   3  [(3-1)*5:3*5]
            m-n条  [m-1:n]   h  [(m-1)*5:n*5]
            """
            start_data=(current_page-1)*show_num # 从第几条数据显示
            end_data=current_page*show_num       # 显示到第几条技术
    
            """
            显示页数
            """
            data_count=models.TeacherTest.objects.count() # 数据的总数量
            page_count,n=divmod(data_count,show_num)
            if n:
                page_count+=1
    
            # 总共展示11页
            max_page=5
            half_max_page=max_page//2
            # 页面上展示的页码从哪开始
            page_start=current_page-half_max_page
            # 页面上展示的页码到哪结束
            page_end=current_page+half_max_page
            # 如果当前页加上一半比总页码数还大
            if page_end>page_count:
                page_end=page_count
                page_start=page_count-max_page
            # 如果当前页减去一半,比1还小
            if page_start<=1:
                page_start=1
                page_end=max_page
    
            page_list=[]
            for p in range(page_start,page_end+1):
                page='<li><a href="/app05/page/?page={0}">{0}</a></li>'.format(p)
                page_list.append(page)
    
            show_data=models.TeacherTest.objects.all()[start_data:end_data]
            return render(request,"page.html",{"allteacher":show_data,"pagecount":page_count,"page_list":page_list})
  • 相关阅读:
    Proj THUDBFuzz Paper Reading: PMFuzz: Test Case Generation for Persistent Memory Programs
    入围 WF 后训练记
    算法竞赛历程
    2021 多校 杭电 第十场
    2021 多校 杭电 第九场
    2021 多校 牛客 第十场
    2021 多校 牛客 第九场
    2021 多校 杭电 第八场
    2021 多校 杭电 第六场
    2021 多校 杭电 第七场
  • 原文地址:https://www.cnblogs.com/fjiqiang/p/10946001.html
Copyright © 2011-2022 走看看