鱼C论坛

 找回密码
 立即注册
查看: 2024|回复: 12

[已解决]django 分页显示 POST 弄不了啊

[复制链接]
发表于 2021-9-13 19:08:04 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
请教一下:
post方法filter 查出来的数据,要分页显示.
if request.method=='GET':
        return render(.......)
    elif request.method=='POST':
                '....filter()....


现在分页请求按理应该是get 请求吧,
怎么让这个 get 分页请求, 模板网页上的 下一页, 怎么跳转到  elif request.method=='POST': 下面的  paginator 的结果
执行出刚才 filter 的分页数据呢??


难道分页也用post 请求, 重复执行filter,
然后改一下  paginator.page(int(page_number)) 中的page_number?? 把模板网页上的 <下一页>绑上page_number这个参数.
这肯定能做 到, 但这样做 感觉有点傻,每点下一页都要重复执行一次filter...浪费资源

另外,想知道,那里可以找到付费指导的服务??
一个人玩,有时一点小问题要弄好久,浪费时间,


最佳答案
2021-9-14 19:27:48
本帖最后由 阿奇_o 于 2021-9-14 19:35 编辑
niceyes 发表于 2021-9-14 18:38
问题一个一个出来, 最终还是回到初始的问题.       分页可以了, 但每点一次页, 后端都要走一次视图函数 ...


背景问题:
1. 你是远程,还是本地?
2. 数据量,具体多少?

其次,你用了models.py 即ORM方式,那肯定会走视图views.py 来实现增删改查数据,加上模板,基本上都要filter(),但速度瓶颈是不是因为它,还不好说。
如果是Django 的ORM瓶颈,可以考虑 不用它的ORM,换用SQLAlchemy+pandas,
或者其他方式,如异步的XHR也可以高性能地访问数据库,
如改用post方法可以不改变URL,从而不用重载整个网页,并用脚本改变部分显示内容(更新数据)。

总之,你要先确定:瓶颈是具体哪里造成的?网络IO?数量量?算法(数据处理方式)?
然后,才能 对症下药……

本帖被以下淘专辑推荐:

  • · django|主题: 61, 订阅: 0
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-9-14 02:03:40 | 显示全部楼层
本帖最后由 阿奇_o 于 2021-9-14 11:35 编辑

可以研究一下 Django的分页方法:https://docs.djangoproject.com/zh-hans/3.1/topics/pagination/
试验:
  1. In [24]: pages = Paginator(Test.objects.get_queryset().order_by('id'), 5)   # ORM获取Test表的所有记录并按id排序。 每页分5条数据。

  2. In [25]: pages.count    # 一共多少条数据
  3. Out[25]: 50

  4. In [26]: pages.num_pages   # 分成了10页
  5. Out[26]: 10

  6. In [27]: pages.page(1).object_list    # 获取第一页的对象列表(每个元素对应着Test表的一行记录)
  7. Out[27]: <QuerySet [<Test: Test object (1)>, <Test: Test object (2)>, <Test: Test object (3)>, <Test: Test object (4)>, <Test: Test object (5)>]>

  8. In [28]: pages.page(2).object_list   # 第二页的
  9. Out[28]: <QuerySet [<Test: Test object (6)>, <Test: Test object (7)>, <Test: Test object (8)>, <Test: Test object (9)>, <Test: Test object (10)>]>

  10. In [29]: for row_obj in pages.page(2).object_list:    # 遍历看看
  11.     ...:     print(row_obj.id, row_obj.sname, row_obj.age)
  12.     ...:
  13. 6 FakeName 18
  14. 7 FakeName 18
  15. 8 FakeName 18
  16. 9 FakeName 18
  17. 10 FakeName 18

  18. In [30]: pages.page(2).next_page_number()   #  
  19. Out[30]: 3

  20. In [32]: curr_page = pages.page(2)

  21. In [33]: curr_page.number     # 当前页为第几页
  22. Out[33]: 2

  23. In [34]: theNextPage = pages.page(curr_page.number + 1)  # 获取下一页的"页对象"(也可以用 curr_page.next_page_number() )

  24. In [35]:

  25. 参考:

  26. https://docs.djangoproject.com/en/3.2/intro/tutorial02/#playing-with-the-api
  27. https://docs.djangoproject.com/zh-hans/3.1/topics/pagination/
  28. https://stackoverflow.com/questions/44033670/python-django-rest-framework-unorderedobjectlistwarning

  29. 补充:
  30. # views.py里
  31. def listing(request):
  32.     Test_list = Test.objects.get_queryset().order_by('id')
  33.     paginator = Paginator(Test_list, 10) # Show 10  per page.

  34.     # page_number = request.GET.get('page', 1)  
  35.     page_num = request.GET['num']  # url要像 ...:8000/page?num=2 (其中'/page'的'page'是你在urls.py里定义的)
  36.     page_obj = paginator.get_page(page_num)
  37.     # page_obj = paginator.get_page(1)
  38.     return render(request, 'listing.html', {'page_obj': page_obj})

  39. 再补充:
  40. # url为 http://...:8000/usepandas  (在urls.py 增加定义 path('usepandas', views.usepandas)
  41. def usepandas(request):
  42.     import pandas as pd
  43.     from sqlalchemy import create_engine
  44.    
  45.     engine = create_engine('mysql+mysqldb://root:123456@localhost/djangodb')
  46.     sql = "select * from djangodb.Test where id >= 11 limit 10"  # 这里就可以用SQL实现分页
  47.     df = pd.read_sql(sql, engine)
  48.     # print(df)
  49.     # return HttpResponse("OK using Pandas.")
  50.     return HttpResponse( "<h3>11-20条记录:<h3>" + df.to_html() )


  51. # 模板:templates/listing.html
  52. <!DOCTYPE html>
  53. <html>
  54. <head>
  55.     <!-- Required meta tags -->

  56.     <!-- Bootstrap CSS 调用在线的前端框架 -->
  57.     <link rel="stylesheet"
  58.     integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  59. </head>
  60. <body>
  61.   
  62.     <p>当前页号: {{ page_obj.number}} </p>

  63.     <p>注:以下需要借助前端框架(如Bootstrap),才能"比较好看地"显示表格和数据</p>
  64.        
  65.     <main role="main" class="container">

  66.         <div class="row"></div>
  67.             <h1>Use the table  </h1>
  68.             <table class="table table-bordered">
  69.                 <thead>
  70.                     <tr>
  71.                         <th>id</th>
  72.                         <th>name</th>
  73.                         <th>age</th>
  74.                     </tr>
  75.                 </thead>
  76.                 <tbody>
  77.                     {% for user in page_obj %}
  78.                     <tr>
  79.                         <td>{{ user.id }}</td>
  80.                         <td>{{ user.sname }}</td>
  81.                         <td>{{ user.age }}</td>
  82.                     </tr>
  83.                     {% endfor %}
  84.                 </tbody>
  85.             </table>

  86.             {% if page_obj.has_other_pages %}
  87.             <ul class="pagination">
  88.                 {% if page_obj.has_previous %}
  89.                 <li><a href="/page?num={{ page_obj.previous_page_number }}"> 上一页&laquo;</a></li>
  90.                 <!-- 如果支持函数调用 page_obj.previous_page_number() 就可以正确跳转。 -->
  91.                 {% else %}
  92.                 <li class="disabled"><span>&laquo;</span></li>
  93.                 {% endif %}
  94.                 {% for i in page_obj.paginator.page_range %}
  95.                 {% if page_obj.number == i %}
  96.                 <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
  97.                 {% else %}
  98.                 <li><a href="/page?num={{ i }}">{{ i }}</a></li>
  99.                 {% endif %}
  100.                 {% endfor %}
  101.                 {% if page_obj.has_next %}
  102.                 <li><a href="/page?num={{ page_obj.next_page_number }}"> 下一页&raquo;</a></li>
  103.                 {% else %}
  104.                 <li class="disabled"><span>&raquo;</span></li>
  105.                 {% endif %}
  106.             </ul>
  107.             {% endif %}
  108.         </div>
  109.     </main>

  110. <h5> <a href="/usepandas">    ------- 简单实现的话,直接用 pandas (点击跳转到)------- </a></h5>


  111. </body>

复制代码


注:以上方法只是我做实验和学习用,实际生产中应该很少有人会这样写,哈哈,通常会用 AJAX技术,以及各种前端框架。
之前只是对Django入了半个门,对于分页等功能,我也是现学现卖,这里主要是为了复习一下MVCT的关系。
具体怎么用,你根据自己的情况,参考着来吧。





注:模板文件 有问题,暂时无法实现点击 <<上/下一页>> 进行跳转。   Django模板语法不支持简单的函数调用!太鸡肋了。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-14 06:57:38 From FishC Mobile | 显示全部楼层
虽然django我不熟悉,可是分页这个东西它只和数据库有关,和get  还是post却是没有关系
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-14 12:23:48 | 显示全部楼层
本帖最后由 阿奇_o 于 2021-9-14 12:26 编辑
阿奇_o 发表于 2021-9-14 02:03
可以研究一下 Django的分页方法:https://docs.djangoproject.com/zh-hans/3.1/topics/pagination/
试验: ...


折腾了半天,总算找到了一种在模板里"上下页跳转"。。

  1. 修改:templates/listing.html

  2.             {% if page_obj.has_other_pages %}
  3.             <ul class="pagination">
  4.                 {% if page_obj.has_previous %}
  5.                 <li><a href="/page?num={{ page_obj.number | add:'-1' }}">&laquo; 上一页</a></li>
  6.                      <!-- 如果支持函数调用 page_obj.previous_page_number() 就可以了。 -->
  7.                      
  8.                 {% else %}
  9.                 <li class="disabled"><span>&laquo; 上一页</span></li>
  10.                 {% endif %}
  11.                 {% for i in page_obj.paginator.page_range %}
  12.                 {% if page_obj.number == i %}
  13.                 <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
  14.                 {% else %}
  15.                 <li><a href="/page?num={{ i }}">{{ i }}</a></li>
  16.                 {% endif %}
  17.                 {% endfor %}
  18.                 {% if page_obj.has_next %}
  19.                 <li><a href="/page?num={{ page_obj.number | add:'1' }}"> 下一页 &raquo;</a></li>
  20.                  <!-- 如果支持函数调用 page_obj.next_page_number() 就可以了 -->
  21.                 {% else %}
  22.                 <li class="disabled"><span> 下一页 &raquo;</span></li>
  23.                 {% endif %}
  24.             </ul>
  25.             {% endif %}
复制代码


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-14 18:35:53 | 显示全部楼层
阿奇_o 发表于 2021-9-14 12:23
折腾了半天,总算找到了一种在模板里"上下页跳转"。。

多谢了,
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-14 18:36:52 | 显示全部楼层
阿奇_o 发表于 2021-9-14 12:23
折腾了半天,总算找到了一种在模板里"上下页跳转"。。

我已弄好,谢谢你的帮助!. 可以分页!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-14 18:38:08 | 显示全部楼层
本帖最后由 niceyes 于 2021-9-14 18:53 编辑
阿奇_o 发表于 2021-9-14 12:23
折腾了半天,总算找到了一种在模板里"上下页跳转"。。


问题一个一个出来, 最终还是回到初始的问题.       分页可以了, 但每点一次页, 后端都要走一次视图函数 filter(),      当 filte()r数据量多时,那个卡啊..  ,这痛点, 不知道怎么解决

  一开始,我是三个关系数据表查,我以为三个mysql 关系数据 外键 ,导致速度慢
后来,我又把三个表合成一个表,,,感觉也没快多少.
后来我又到淘宝上请人帮忙解决, 速度感觉还是不行,,, 如果不分页,一次加载完成 , 分页后,每页都要重新加载一次,

  search_rebar=Rebar.objects.filter(project_name__contains=project_name)

        for rebar in search_rebar[int(page_num)*20-20:int(page_num)*20]: #一页20条数据
            #把查询结果生成字典
            result_dict={.....                     
                        }
            result_list.append(result_dict)
        import math
        #页面总数
        page_count = math.ceil(len(search_rebar)/20)
        #当前页
        page_c=int(page_num)
        #下一页
        next_page_number = page_num+1 if page_count>page_num else False

影响速度是FOR ...        ,我用excal 写vba代码 ,     select速度要都比django快多了, 晕死
        #上一页
        previous_page_number = page_num-1 if page_num>1 else False
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-14 19:27:48 | 显示全部楼层    本楼为最佳答案   
本帖最后由 阿奇_o 于 2021-9-14 19:35 编辑
niceyes 发表于 2021-9-14 18:38
问题一个一个出来, 最终还是回到初始的问题.       分页可以了, 但每点一次页, 后端都要走一次视图函数 ...


背景问题:
1. 你是远程,还是本地?
2. 数据量,具体多少?

其次,你用了models.py 即ORM方式,那肯定会走视图views.py 来实现增删改查数据,加上模板,基本上都要filter(),但速度瓶颈是不是因为它,还不好说。
如果是Django 的ORM瓶颈,可以考虑 不用它的ORM,换用SQLAlchemy+pandas,
或者其他方式,如异步的XHR也可以高性能地访问数据库,
如改用post方法可以不改变URL,从而不用重载整个网页,并用脚本改变部分显示内容(更新数据)。

总之,你要先确定:瓶颈是具体哪里造成的?网络IO?数量量?算法(数据处理方式)?
然后,才能 对症下药……
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-16 14:33:31 | 显示全部楼层
阿奇_o 发表于 2021-9-14 19:27
背景问题:
1. 你是远程,还是本地?
2. 数据量,具体多少?

还要请教你一个问题,        我有多张表, 共同ID ,但ID是不重复.             是不是要在多张表之外,再专建一张ID表
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-16 15:10:36 | 显示全部楼层
本帖最后由 阿奇_o 于 2021-9-16 15:18 编辑
niceyes 发表于 2021-9-16 14:33
还要请教你一个问题,        我有多张表, 共同ID ,但ID是不重复.             是不是要在多张表之外,再专 ...


得看 具体表与表的关系,以及具体的需求,
若根据"关系建模的第三范式"会尽可能拆分,但这不是必须的,要看具体情况。

ps: 查询速度"很慢"的问题,解决了? 问题出在哪?(我也好奇是哪的问题...)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-16 16:05:14 | 显示全部楼层
阿奇_o 发表于 2021-9-16 15:10
得看 具体表与表的关系,以及具体的需求,
若根据"关系建模的第三范式"会尽可能拆分,但这不是必须的 ...

问题解决了, django filter很快, 主要原因是要避免(一定不能)在视图函数中 遍历filter()出来的数据,      在视图函数中遍历,会造成重复执行,        应该在模板中对分好的页,进行遍历, 我淘宝请人都没解决好, 还是自已看官方文档,弄明白了原因.
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-16 16:07:16 | 显示全部楼层
阿奇_o 发表于 2021-9-16 15:10
得看 具体表与表的关系,以及具体的需求,
若根据"关系建模的第三范式"会尽可能拆分,但这不是必须的 ...

原因很简单,遇到熟练的人一句话就解决了, 自学要绕很多弯路
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-16 17:40:36 | 显示全部楼层
niceyes 发表于 2021-9-16 16:05
问题解决了, django filter很快, 主要原因是要避免(一定不能)在视图函数中 遍历filter()出来的数据,      ...

TableX.objects.filter()出来的是一个QuerySet对象,应该是一个类似"生成器"的东西,
在views.py里分页 也行(把分页对象 传给模板来处理就好了),
但 在视图里对它遍历 或 存到一个列表里,就很消耗资源了。。 你应该是这种情况。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-24 14:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表