django 分页显示 POST 弄不了啊
请教一下: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...浪费资源
另外,想知道,那里可以找到付费指导的服务??
一个人玩,有时一点小问题要弄好久,浪费时间,
本帖最后由 阿奇_o 于 2021-9-14 11:35 编辑
可以研究一下 Django的分页方法:https://docs.djangoproject.com/zh-hans/3.1/topics/pagination/
试验:
In : pages = Paginator(Test.objects.get_queryset().order_by('id'), 5) # ORM获取Test表的所有记录并按id排序。 每页分5条数据。
In : pages.count # 一共多少条数据
Out: 50
In : pages.num_pages # 分成了10页
Out: 10
In : pages.page(1).object_list # 获取第一页的对象列表(每个元素对应着Test表的一行记录)
Out: <QuerySet [<Test: Test object (1)>, <Test: Test object (2)>, <Test: Test object (3)>, <Test: Test object (4)>, <Test: Test object (5)>]>
In : pages.page(2).object_list # 第二页的
Out: <QuerySet [<Test: Test object (6)>, <Test: Test object (7)>, <Test: Test object (8)>, <Test: Test object (9)>, <Test: Test object (10)>]>
In : 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 : pages.page(2).next_page_number() #
Out: 3
In : curr_page = pages.page(2)
In : curr_page.number # 当前页为第几页
Out: 2
In : theNextPage = pages.page(curr_page.number + 1)# 获取下一页的"页对象"(也可以用 curr_page.next_page_number() )
In :
参考:
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 10per 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的关系。
具体怎么用,你根据自己的情况,参考着来吧。
{:10_248:}
注:模板文件 有问题,暂时无法实现点击 <<上/下一页>> 进行跳转。 Django模板语法不支持简单的函数调用!太鸡肋了。。
虽然django我不熟悉,可是分页这个东西它只和数据库有关,和get还是post却是没有关系 本帖最后由 阿奇_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 %}
{:10_261:} 阿奇_o 发表于 2021-9-14 12:23
折腾了半天,总算找到了一种在模板里"上下页跳转"。。
多谢了, 阿奇_o 发表于 2021-9-14 12:23
折腾了半天,总算找到了一种在模板里"上下页跳转"。。
我已弄好,谢谢你的帮助!. 可以分页! 本帖最后由 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: #一页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 本帖最后由 阿奇_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?数量量?算法(数据处理方式)?
然后,才能 对症下药……
阿奇_o 发表于 2021-9-14 19:27
背景问题:
1. 你是远程,还是本地?
2. 数据量,具体多少?
还要请教你一个问题, 我有多张表, 共同ID ,但ID是不重复. 是不是要在多张表之外,再专建一张ID表 本帖最后由 阿奇_o 于 2021-9-16 15:18 编辑
niceyes 发表于 2021-9-16 14:33
还要请教你一个问题, 我有多张表, 共同ID ,但ID是不重复. 是不是要在多张表之外,再专 ...
得看 具体表与表的关系,以及具体的需求,
若根据"关系建模的第三范式"会尽可能拆分,但这不是必须的,要看具体情况。
ps: 查询速度"很慢"的问题,解决了? 问题出在哪?(我也好奇是哪的问题...) 阿奇_o 发表于 2021-9-16 15:10
得看 具体表与表的关系,以及具体的需求,
若根据"关系建模的第三范式"会尽可能拆分,但这不是必须的 ...
问题解决了, django filter很快, 主要原因是要避免(一定不能)在视图函数中 遍历filter()出来的数据, 在视图函数中遍历,会造成重复执行, 应该在模板中对分好的页,进行遍历, 我淘宝请人都没解决好, 还是自已看官方文档,弄明白了原因. 阿奇_o 发表于 2021-9-16 15:10
得看 具体表与表的关系,以及具体的需求,
若根据"关系建模的第三范式"会尽可能拆分,但这不是必须的 ...
原因很简单,遇到熟练的人一句话就解决了, 自学要绕很多弯路 niceyes 发表于 2021-9-16 16:05
问题解决了, django filter很快, 主要原因是要避免(一定不能)在视图函数中 遍历filter()出来的数据, ...
TableX.objects.filter()出来的是一个QuerySet对象,应该是一个类似"生成器"的东西,
在views.py里分页 也行(把分页对象 传给模板来处理就好了),
但 在视图里对它遍历 或 存到一个列表里,就很消耗资源了。。 你应该是这种情况。。
页:
[1]