鱼C论坛

 找回密码
 立即注册
查看: 1783|回复: 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
想知道小甲鱼最近在做啥?请访问 -> 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/
试验:
In [24]: pages = Paginator(Test.objects.get_queryset().order_by('id'), 5)   # ORM获取Test表的所有记录并按id排序。 每页分5条数据。

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

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

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

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

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

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

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

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

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

In [35]: 

参考:

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

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

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

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


# 模板:templates/listing.html
<!DOCTYPE html>
<html>
<head>
    <!-- Required meta tags -->

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

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

        <div class="row"></div>
            <h1>Use the table  </h1>
            <table class="table table-bordered">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>age</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user in page_obj %}
                    <tr>
                        <td>{{ user.id }}</td>
                        <td>{{ user.sname }}</td>
                        <td>{{ user.age }}</td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>

            {% if page_obj.has_other_pages %}
            <ul class="pagination">
                {% if page_obj.has_previous %}
                <li><a href="/page?num={{ page_obj.previous_page_number }}"> 上一页«</a></li> 
                <!-- 如果支持函数调用 page_obj.previous_page_number() 就可以正确跳转。 -->
                {% else %}
                <li class="disabled"><span>«</span></li>
                {% endif %}
                {% for i in page_obj.paginator.page_range %}
                {% if page_obj.number == i %}
                <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
                {% else %}
                <li><a href="/page?num={{ i }}">{{ i }}</a></li>
                {% endif %}
                {% endfor %}
                {% if page_obj.has_next %}
                <li><a href="/page?num={{ page_obj.next_page_number }}"> 下一页»</a></li>
                {% else %}
                <li class="disabled"><span>»</span></li>
                {% endif %}
            </ul>
            {% endif %}
        </div>
    </main>

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


</body>

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





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

使用道具 举报

发表于 2021-9-14 06:57:38 From FishC Mobile | 显示全部楼层
虽然django我不熟悉,可是分页这个东西它只和数据库有关,和get  还是post却是没有关系
想知道小甲鱼最近在做啥?请访问 -> 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/
试验: ...


折腾了半天,总算找到了一种在模板里"上下页跳转"。。
修改:templates/listing.html

            {% if page_obj.has_other_pages %}
            <ul class="pagination">
                {% if page_obj.has_previous %}
                <li><a href="/page?num={{ page_obj.number | add:'-1' }}">« 上一页</a></li>
                     <!-- 如果支持函数调用 page_obj.previous_page_number() 就可以了。 -->
                     
                {% else %}
                <li class="disabled"><span>« 上一页</span></li>
                {% endif %}
                {% for i in page_obj.paginator.page_range %}
                {% if page_obj.number == i %}
                <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
                {% else %}
                <li><a href="/page?num={{ i }}">{{ i }}</a></li>
                {% endif %}
                {% endfor %}
                {% if page_obj.has_next %}
                <li><a href="/page?num={{ page_obj.number | add:'1' }}"> 下一页 »</a></li>
                 <!-- 如果支持函数调用 page_obj.next_page_number() 就可以了 -->
                {% else %}
                <li class="disabled"><span> 下一页 »</span></li>
                {% endif %}
            </ul>
            {% endif %}

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

多谢了,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

我已弄好,谢谢你的帮助!. 可以分页!
想知道小甲鱼最近在做啥?请访问 -> 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
想知道小甲鱼最近在做啥?请访问 -> 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?数量量?算法(数据处理方式)?
然后,才能 对症下药……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

还要请教你一个问题,        我有多张表, 共同ID ,但ID是不重复.             是不是要在多张表之外,再专建一张ID表
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

ps: 查询速度"很慢"的问题,解决了? 问题出在哪?(我也好奇是哪的问题...)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

原因很简单,遇到熟练的人一句话就解决了, 自学要绕很多弯路
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-22 14:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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