• ◢Django 自写分页与使用


    目录

    1、设置分页样式,并展示到浏览器

     2、模拟页码

     3、生成分页

    4、数据显示

     5、上一页下一页

    6、数据库的数据分页

     7、封装分页

    8、使用封装好的分页

    建立好app后,设置路径path('in2/',views.in2),视图def in2(request): ,HTML: in2.html

    1、设置分页样式,并展示到浏览器

    1. def in2(request):
    2. return render(request,'in2.html')
    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Titletitle>
    6. <style>
    7. *{
    8. padding: 0;
    9. list-style: none;
    10. margin: 0;
    11. }
    12. span{
    13. display: inline-block;
    14. width: 40px;
    15. text-align: center;
    16. font-size: 20px;
    17. border: 1px solid;
    18. background-color: #2aabd2;
    19. }
    20. a{
    21. text-decoration: none;
    22. color: white;
    23. }
    24. style>
    25. head>
    26. <body>
    27. <span><a>1a>span>
    28. body>
    29. html>

     2、模拟页码

    1. def in2(request):
    2. # 假设有100条数据
    3. data_count = 100 #350
    4. #每页有8条数据
    5. page_size = 8
    6. #共有多少页
    7. page_count, count=divmod(data_count,page_size)
    8. if count:
    9. page_count+=1
    10. page_string = ''
    11. for i in range(page_count):
    12. page_string+=f"{i}"
    13. #page_string = mark_safe("".join(page_string))
    14. return render(request,'in2.html',{"page_string":page_string})

    若是在html中直接导入page_string 那就是一个字符串,

    需要将循环生成的page_string进行,【取消注释】

    page_string = mark_safe("".join(page_string))

    作用是:将字符串列表(`page_string`)中的元素连接起来,并将结果标记为安全的HTML内容。使用`join()`函数将字符串列表中的所有元素连接在一起,然后`mark_safe()`函数将连接起来的字符串标记为安全的,这样在显示HTML内容时,就不会对其中的标签和特殊字符进行转义处理。通常用于在模板中生成动态的HTML内容,以避免对HTML标签和特殊字符进行转义。

     3、生成分页

    数据量增多后,页码就变多了,需要设置显示的分页,在当前页的基础上显示前5页后5页,多出的页码不显示

    为每个a标签附带参数page,使用字符串拼接,用for循环标明每个a所附带的参数,

    点击a标签,发送的是get请求,GET请求没有获得page时,默认为第一页,点击之后,url自动携带page参数,每次点击获取该a标签的携带page参数,用作当前页

    1. def in2(request):
    2. #默认设置当前页为1,若有get请求传递过来的当前页,则进行更改
    3. if request.GET.get('page'):
    4. current_page = int(request.GET.get('page'))
    5. else:
    6. current_page = 1
    7. data_count = 350
    8. page_size = 8
    9. page_count, count=divmod(data_count,page_size)
    10. if count:
    11. page_count+=1
    12. #设置当前页的前后可见页数为5
    13. plus = 5
    14. #当前页小于等于5 起始页始终为1 ;当前页大于5 起始页为当前页减5
    15. if current_page <= plus + 1:
    16. start_page = 1
    17. else:
    18. start_page = current_page - plus
    19. # 当前页大于等于最终点页 结束页始终为终点页 ;当前页小于终点页减5 结束页为当前页+5
    20. if current_page >= page_count - plus:
    21. end_page = page_count
    22. else:
    23. end_page = current_page + plus
    24. page_string = ''
    25. for i in range(start_page, end_page + 1):
    26. page_string += f"{i}>{i}"
    27. page_string = mark_safe("".join(page_string))
    28. context={
    29. "current_page":current_page,
    30. "start_page":start_page,
    31. "end_page" :end_page,
    32. "page_string":page_string,
    33. }
    34. return render(request,'in2.html',context)

    成功后,为了显示当前页的不同,需要在for循环那里,增加一个if,用以判断,i与当前页是否相同,相同则为该页加上不同的样式

    1. for i in range(start_page, end_page + 1):
    2. if i == current_page:
    3. page_string += f"{i}>{i}"
    4. else:
    5. page_string += f"{i}>{i}"

    4、数据显示

    增加数据的时候,注意最后一页数据是不满的[44*8=352],一共有350条数据,所以最后一页的end为总数据条数。

    1. #获取数据的起始位置与结束位置[1,8],[9,16]
    2. start = int(current_page - 1 ) * page_size + 1
    3. if current_page == page_count:#当前页是最后一页时,数据并不是8条数据
    4. end = data_count
    5. else:
    6. end = int(current_page) * page_size
    7. print(start,end)

    给context字典中补充起始数据,与结束数据,这里采用的是整型数字用来模拟数据总数,在HTML中for不能同平时使用,不能迭代整型数据,直接传入range(start,end,step)作为迭代器

    context={

            "data":range(start,end+1),

    }

     在HTML中遍历data

    1. <style>
    2. .data{
    3. width: 300px;
    4. height: 166px;
    5. border: 1px solid #8a6d3b;
    6. margin-bottom: 30px;
    7. }
    8. style>
    9. <body>
    10. <div class="data">
    11. {% for i in data %}
    12. <li>这是第 {{ i }} 条数据li>
    13. {% endfor %}
    14. div>
    15. body>

                                

     5、上一页下一页

    在点击页码的情况下增加上一页下一页的按钮,当前看到的最后页码变为第一个页码。

    看见第一页不显示上一页按钮,同样最后一页也不带按钮。

    处于看不见首页,但又不超过加减页时,点击上一页会跳出合适的页码,应当设置page=1,拉回跳转位置,放置page变为负数,尾页也一样。

    页码满足加减页时,实行最后一个页码变第一个页码,在当前页的页码基础上 加上 或 减去 plus的2倍

    1. # 上一页,下一页
    2. if current_page <= plus +1:#当前页在前5页时,不需要上一页
    3. pre = ''
    4. else:
    5. if current_page <= plus * 2 :#当前页处于5-10页时,点击上一页,跳转到第1页
    6. pre=f'{1}>首页'
    7. else:
    8. if current_page >= page_count - plus:
    9. next = ''
    10. else:
    11. if current_page >= page_count - plus * 2:
    12. else:

    整合分页和上下页的程序,减少if的判断

    6、数据库的数据分页

    605/8=75,605%8=5【最后一页是75,有5条数据】第一列是表的id不是序号,中间有删掉的id,所以最终值不为605

    data_count =  models.表名.objects.all().count()

    1. <div class="data">
    2. {% for i in data %}
    3. <li><span>{{ i.id }}span> <span style="width: 130px">{{ i.phone }}span> <span>{{ i.price }}span>li>
    4. {% endfor %}
    5. div>

    在 SQL Server 中,索引是从 1 开始计数的,需要 +1,而MySql数据库的索引是从0开始,所以不用加,注意区别自己使用的数据起始索引  

     7、封装分页

    建立软件包,命名为utils

     在utils中建立SplitPage.py,整合前面程序,该封装的封装,该方法体的方法体,page_size不写默认为8,写则加载

    1. from django.utils.safestring import mark_safe
    2. class Splitpagenumber:
    3. def __init__(self,request, queryset, page_size=8, plus=5, ):
    4. #定义变量,方法体实现分页
    5. if request.GET.get('page'):
    6. self.current_page = int(request.GET.get('page'))
    7. else:
    8. self.current_page = 1
    9. '''可分为多少个页码'''
    10. self.page_count,count = divmod(queryset.count(), page_size)
    11. if count:
    12. self.page_count += 1
    13. start = int(self.current_page - 1) * page_size
    14. if self.current_page == self.page_count: # 当前页是最后一页时,数据并不是8条数据
    15. end = queryset.count()
    16. else:
    17. end = int(self.current_page) * page_size
    18. self.data = queryset[start:end]
    19. self.plus =plus
    20. def html(self):
    21. #实现 起始页,结束页 ,与 上一页下一页
    22. if self.current_page <= self.plus + 1:
    23. start_page = 1
    24. pre = ''
    25. else:
    26. start_page = self.current_page - self.plus
    27. if self.current_page <= self.plus * 2: # 当前页处于5-10页时,点击上一页,跳转到第1页
    28. pre = f'{1}>首页'
    29. else:
    30. # 当前页大于等于最终点页 结束页始终为终点页 ;当前页小于终点页减5 结束页为当前页+5
    31. if self.current_page >= self.page_count - self.plus:
    32. end_page = self.page_count
    33. next = ''
    34. else:
    35. end_page = self.current_page + self.plus
    36. if self.current_page >= self.page_count - self.plus * 2:
    37. else:
    38. """ 生成html格式 """
    39. page_string = ''
    40. page_string += pre
    41. for i in range(start_page, end_page + 1):
    42. if i == self.current_page:
    43. page_string += f"{i}>{i}"
    44. else:
    45. page_string += f"{i}>{i}"
    46. page_string += next
    47. page_string = mark_safe("".join(page_string))
    48. return page_string

    8、使用封装好的分页 

    完善in3的路径联系,然后运行in3

    1. from app02.utils import SplitPage
    2. def in3(request):
    3. queryset = models.User.objects.all()
    4. page_object = SplitPage.Splitpagenumber(request, queryset)
    5. context={
    6. "info":page_object.data,
    7. "page_string":page_object.html()
    8. }
    9. return render(request,'in3.html',context)

    默认分页 【数据显示添加css】

    1. page_object = SplitPage.Splitpagenumber(request, queryset,page_size=31,plus=5)
    2. page_object = SplitPage.Splitpagenumber(request, queryset,page_size=2,plus=10)

    只截了最后一页,分页显示的就不一样,但数据相同 

  • 相关阅读:
    openai自定义API操作 API 返回值说明
    C基础知识-结构体(详解)
    (附源码)springboot课程评价系统 毕业设计 211004
    【SNUT集训1】排序 二分 前缀和 差分(6 / 16)
    记录在一次bufio.Reader的错误使用中引起的思考
    【原理篇】四、自定义starter
    网络面试一百问<待整理>
    JVM理解(一)
    一个更好的IP工具箱MyIP
    python安装selenium(Firefox和Chrome)+元素定位
  • 原文地址:https://blog.csdn.net/m0_62836433/article/details/134367514