分页
当我们的数据过多是,我们需要对数据进行分页,即每页显示多少行,有多少页,好在Django已经为我们准备好了,直接套用即可
视图函数
下方我是将三个数据表中的数据合在一起,准备渲染到界面,
注意:三个数据表中需要有一个可以分辨其实不同数据表的字段,方便我们在前端分别渲染
我们给一个page参数,默认是1
def allprodect(request,page = 1): | |
# 获取cookie中的usid值,不存在则默认0 | |
usid = request.COOKIES.get('usid', 0) | |
# 查询数据库中是否存在用户 | |
user = UserMondel.objects.filter(id=usid).first() | |
# 如果usid等于0,则代表用户不存在,则需定位到登录页 | |
if usid == 0: | |
return redirect(reverse('login')) | |
per_page = 10 | |
injection = injection_machine.objects.filter().all() | |
machining = machining_machine.objects.filter().all() | |
robots = robot.objects.filter().all() | |
allinfo = list(injection) + list(machining) + list(robots) | |
# 分页器 | |
paginator = Paginator(allinfo, per_page) | |
# 获取第几页數據 | |
injection_page = paginator.page(page) | |
# 页码范围,可以遍历 | |
pages = paginator.page_range | |
return render(request, 'allprodect.html', | |
{'injection_page': injection_page, 'pages': pages, 'pageone': page, 'user': user}) |
URL
在URL当中设置带参请求和不带参两个请求
path('allprodect/<int:page>',allprodect,name='allprodect'), | |
path('allprodect/',allprodect,name='allprodect'), |
前端
使用for循环对其进行渲染,我这边因为三个数据库中显示的字段都是一样的,所以可以放在一起,如果你的是不同的,则需要分别不同渲染
{% for inject in injection_page %} | |
{% csrf_token %} | |
<div class="row mb-3 custom-card col-md-8 custom-card-hover"> <!-- 添加 custom-card-hover 类 --> | |
<a href="#" class="text-decoration-none col-md-10 d-flex"> | |
<!-- 图片区域在左边 --> | |
<div class="col-md-4"> | |
<img src="{{ inject.photo.url }}" alt="图片" class="custom-img" style="height: 120px;width:auto;max-width: 100%;object-fit: contain"> | |
</div> | |
<!-- 文字数据区域 --> | |
<div class="col-md-8"> | |
<!-- 左边参数 --> | |
<div class="row"> | |
<div class="col-md-6"> | |
<ul> | |
{% if inject.classify is null %} | |
<li>類別:{{ inject.classifys }}</li> | |
{% else %} | |
<li>類別:{{ inject.classify }}</li> | |
{% endif %} | |
<li>品牌:{{ inject.brand }}</li> | |
<li>型号:{{ inject.model }}</li> | |
<li>年份:{{ inject.year }}</li> | |
</ul> | |
</div> | |
<!-- 右边参数 --> | |
<div class="col-md-6"> | |
<ul> | |
{% if inject.is_Shelves == 1%} | |
<li>状态:上架</li> | |
{% else %} | |
<li>状态:下架</li> | |
{% endif %} | |
</ul> | |
</div> | |
</div> | |
</div> | |
</a> | |
<!-- 按钮区域 --> | |
<div class="col-md-2 d-flex align-items-center"> | |
{% if inject.classify is null %} | |
<button type="button" class="btn btn-success mx-1" onclick="prodectshelves('{{ inject.id }}','{{ inject.classifys }}','{{ user.id }}')">上架</button> | |
{# <li>類別:{{ inject.classifys }}</li>#} | |
{% else %} | |
{# <li>類別:{{ inject.classify }}</li>#} | |
<button type="button" class="btn btn-success mx-1" onclick="prodectshelves('{{ inject.id }}','{{ inject.classify }}','{{ user.id }}')">上架</button> | |
{% endif %} | |
{% if inject.classify is null %} | |
<button type="button" class="btn btn-danger mx-1" onclick="prodectshelvesunder('{{ inject.id }}','{{ inject.classifys }}','{{ inject.id }}')">下架</button> | |
{% else %} | |
{# <li>類別:{{ inject.classify }}</li>#} | |
<button type="button" class="btn btn-danger mx-1" onclick="prodectshelvesunder('{{ inject.id }}','{{ inject.classify }}','{{ inject.id }}')">下架</button> | |
{% endif %} | |
</div> | |
</div> | |
<hr> | |
{% endfor %} |
分页组件
injection_page.previous_page_number中的previous_page_number会获取当前页面的上一页
injection_page.next_page_number中的next_page_number会获取当前页面的下一页
pages是数据所有的页面,可以进行循环并显示
<!-- 分页组件 --> | |
<nav aria-label="Page navigation example"> | |
<ul class="pagination"> | |
{% if injection_page.has_previous %} | |
<li class="page-item"><a class="page-link" href="{% url 'allprodect' injection_page.previous_page_number %}">上一页</a></li> | |
{% endif %} | |
{% for page in pages %} | |
<li class="page-item"><a class="page-link" href="{% url 'allprodect' page %}">{{ page }}</a></li> | |
{% endfor %} | |
{% if injection_page.has_next %} | |
<li class="page-item"><a class="page-link" href="{% url 'allprodect' injection_page.next_page_number%}">下一页</a></li> | |
{% endif % | |
</ul> | |
</nav> |
筛选查询
目前有一个筛选查询的需求,可以查询已上架和下架的产品,并且如果数据过多,以分页的页面进行展示
视图函数
在这个视图函数中,我们首先判断其实GET请求,并在GET请求中获取来自前端页面的state参数值,以此来查询上架和未上架的产品,数据库字段使用的是布尔值,也就是1和0,故咋前端页面传值是只需要传1或者0 即可查询不同的值数据,
因为筛选的是三个数据表中的数据,故需要对其进行数据合并,然后传送至前端进行渲染显示
def Searchstate(request,page = 1): | |
# 获取cookie中的usid值,不存在则默认0 | |
usid = request.COOKIES.get('usid', 0) | |
# 查询数据库中是否存在用户 | |
user = UserMondel.objects.filter(id=usid).first() | |
# 如果usid等于0,则代表用户不存在,则需定位到登录页 | |
if usid == 0: | |
return redirect(reverse('login')) | |
if request.method == 'GET': | |
state = request.GET.get("state") | |
per_page = 5 | |
injection = injection_machine.objects.filter(is_Shelves=state).all() | |
machining = machining_machine.objects.filter(is_Shelves=state).all() | |
robots = robot.objects.filter(is_Shelves=state).all() | |
allinfo = list(injection) + list(machining) + list(robots) | |
# 分页器 | |
paginator = Paginator(allinfo, per_page) | |
# 获取第几页數據 | |
injection_page = paginator.page(page) | |
# 页码范围,可以遍历 | |
pages = paginator.page_range | |
return render(request, 'Searchstate.html', | |
{'injection_page': injection_page, 'pages': pages, 'pageone': page, 'user': user}) |
URL
带参进行分页时使用,不带参正常请求
path('Searchstate/<int:page>',Searchstate,name='Searchstate'), | |
path('Searchstate/',Searchstate,name='Searchstate'), |
前端
注意:在下面代码中,form表单中,提交的地址是:{% url 'Searchstate' 1%}给路径一个默认值是1,方式是GET,提交ID是state的值,
<div class="container mt-4"> <!-- 添加 mt-4 类来设置顶部间隙 --> | |
<hr> | |
<form method="get" action="{% url 'Searchstate' 1%}" class="form-inline align-items-end"> <!-- 添加 align-items-end 类 --> | |
<div class="form-group mb-2 mr-2"> | |
<label for="state">狀態:</label> | |
<select id="state" name="state" class="form-control"> | |
<option value="1">上架</option> | |
<option value="0">下架</option> | |
<!-- 添加更多选项 --> | |
</select> | |
</div> | |
<div class="form-group mb-2"> | |
<button type="submit" class="btn btn-primary">搜索</button> | |
</div> | |
</form> | |
{% for inject in injection_page %} | |
<div class="row mb-3 custom-card col-md-8 custom-card-hover"> <!-- 添加 custom-card-hover 类 --> | |
<a href="#" class="text-decoration-none col-md-10 d-flex"> | |
<!-- 图片区域在左边 --> | |
<div class="col-md-4"> | |
<img src="{{ inject.photo.url }}" alt="图片" class="custom-img" style="height: 120px;width:auto;max-width: 100%;object-fit: contain"> | |
</div> | |
<!-- 文字数据区域 --> | |
<div class="col-md-8"> | |
<!-- 左边参数 --> | |
<div class="row"> | |
<div class="col-md-6"> | |
<ul> | |
{% if inject.classify is null %} | |
<li>類別:{{ inject.classifys }}</li> | |
{% else %} | |
<li>類別:{{ inject.classify }}</li> | |
{% endif %} | |
<li>品牌:{{ inject.brand }}</li> | |
<li>型号:{{ inject.model }}</li> | |
<li>年份:{{ inject.year }}</li> | |
</ul> | |
</div> | |
<!-- 右边参数 --> | |
<div class="col-md-6"> | |
<ul> | |
{% if inject.is_Shelves == 1%} | |
<li>状态:上架</li> | |
{% else %} | |
<li>状态:下架</li> | |
{% endif %} | |
</ul> | |
</div> | |
</div> | |
</div> | |
</a> | |
<!-- 按钮区域 --> | |
<div class="col-md-2 d-flex align-items-center"> | |
{% if inject.classify is null %} | |
<button type="button" class="btn btn-success mx-1" onclick="searchprodectshelves('{{ inject.id }}','{{ inject.classifys }}','{{ user.id }}')">上架</button> | |
{# <li>類別:{{ inject.classifys }}</li>#} | |
{% else %} | |
{# <li>類別:{{ inject.classify }}</li>#} | |
<button type="button" class="btn btn-success mx-1" onclick="searchprodectshelves('{{ inject.id }}','{{ inject.classify }}','{{ user.id }}')">上架</button> | |
{% endif %} | |
{% if inject.classify is null %} | |
<button type="button" class="btn btn-danger mx-1" onclick="searchprodectshelvesunder('{{ inject.id }}','{{ inject.classifys }}','{{ inject.id }}')">下架</button> | |
{% else %} | |
{# <li>類別:{{ inject.classify }}</li>#} | |
<button type="button" class="btn btn-danger mx-1" onclick="searchprodectshelvesunder('{{ inject.id }}','{{ inject.classify }}','{{ inject.id }}')">下架</button> | |
{% endif %} | |
</div> | |
</div> | |
<hr> | |
{% endfor %} | |
</div> |
点击搜索后,地址是:http://127.0.0.1:8000/Searchstate/?state=1
因为我们的数据有多个,还需要进行分页,故在分页组件中要特别指定?state={{ request.GET.state }}会将GET请求的参数带上查询,
如第第二页就是:http://127.0.0.1:8000/Searchstate/2?state=1
<!-- 分页组件 --> | |
<nav aria-label="Page navigation example"> | |
<ul class="pagination"> | |
{% if injection_page.has_previous %} | |
<li class="page-item"><a class="page-link" href="{% url 'Searchstate' injection_page.previous_page_number %}?state={{ request.GET.state }}">上一页</a></li> | |
{% endif %} | |
{% for page in pages %} | |
<li class="page-item"><a class="page-link" href="{% url 'Searchstate' page %}?state={{ request.GET.state }}">{{ page }}</a></li> | |
{% endfor %} | |
{% if injection_page.has_next %} | |
<li class="page-item"><a class="page-link" href="{% url 'Searchstate' injection_page.next_page_number%}?state={{ request.GET.state }}">下一页</a></li> | |
{% endif %} | |
</ul> | |
</nav> |
总结:
分页比较简单,基本上有官网文档即可操作上手,但在进行筛选分页时耗了一点时间,记录一下,下次少走弯路
我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!