数据的翻页和搜素功能
目录
1.实现搜素功能
2.实现翻页功能
一、实现搜素功能
我们到bootstrap官网, 点击组件, 然后找到输入框组, 并点击作为额外元素的按钮。

我们需要使用上面红色框里面的组件, 就是搜素组件, 代码部分就是下面红色框框出来的部分。
把这里的代码复制到assets_list.html里面:
html
{% extends "index/model_tmp.html" %}
{% block content %}
<div class="container">
<a href="/assets/add/" class="btn btn-success">添加信息</a>
{# 实现搜素查询, 将查询的框和按钮都放在右边 #}
<div style="float: right">
{# 这里面搜素信息, 需要用到get请求方法, 所以还是要用到form, method是get, 之后使用搜素功能会在网址里面多一个参数, 叫做search, 网址格式变为http://ip:port/路径?search=搜素的内容 #}
<form method="get">
{# 这里面就是网上复制粘贴的代码 #}
<div class="input-group" style="float: right;width: 300px;">
<input type="text" class="form-control" name="search" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">搜索</button>
</span>
</div>
</form>
</div>
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">资产表</h3>
</div>
<div class="panel-body">
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>手机号</th>
<th>状态</th>
<th>创建时间</th>
<th>使用者</th>
<th>价格</th>
</tr>
</thead>
<tbody>
{% for data in assets_list %}
<tr>
<th scope="row">{{ data.id }}</th>
<td>{{ data.mobile }}</td>
{% if data.status == 1 %}
<td style="color: green">{{ data.get_status_display }}</td>
{% else %}
<td style="color: red">{{ data.get_status_display }}</td>
{% endif %}
<td>{{ data.create_time|date:"Y-m-d" }}</td>
<td>{{ data.user.name }}</td>
<td>{{ data.price }}</td>
<td style="color: green">
<a href="/assets/{{ data.id }}/modify"><span style="color: green;"
class="glyphicon glyphicon-pencil"
aria-hidden="true"></span></a>
<a href="/assets/{{ data.id }}/del/"><span style="color: red;"
class="glyphicon glyphicon-trash"
aria-hidden="true"></span></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
python
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.shortcuts import render, redirect
from django.utils.safestring import mark_safe
from django import forms
from project_one import models
# Create your views here.
def assets(request):
# 搜索信息
dict_data = {}
# 获取搜素框里的内容, 就是获取网址里面的search参数的值
value = request.GET.get('search')
if value:
# 在表格中搜素包含输入框当中的数据, 这里搜素的是手机号, key为mobile__contains
dict_data["mobile__contains"] = value
# 通过搜素框里面的内容, 在表格里查找手机号, 将查找的结果展示出来
assets_list = models.Assets.objects.filter(**dict_data)
return render(request, "assets/assets_list.html", {"assets_list": assets_list})
这里的assets函数, 还是上次写好的函数, 路由也是上次配置好的, 我们这篇文章只需要修改这个函数里面的内容即可。
运行结果:

这里面有很多数据, 我们使用搜素功能看看有什么结果。
假如我们搜素158:

页码会展示带有158的电话号码(这个搜素, 可以搜素匹配手机号的任意位置, 但是搜所的内容, 和匹配的电话里面的数字必须连续匹配的上, 比如搜素框里面是33589, 但是实际有个电话号码有部分包含33580, 这种情况就匹配不出来)。
还有当我们在搜索框没有任何内容的时候, 再点击搜索按钮, 就会把所有数据都展示出来。
这个就是搜素功能。整体代码相对简单, 不过需要注意的是: value = request.GET.get('search')这行代码, 是用户获取在url里面的search参数的值, 比如象上面我搜索的158, 在url里面后面跟着?search=158, 所以这里的value, 获取的就是158。if value: // 在表格中搜素包含输入框当中的数据, 这里搜素的是手机号, key为mobile__contains dict_data["mobile__contains"] = value
这里的代码意思是如果获取到了搜索框里面的内容, 那就添加字典里面, 并且
key为mobile__contains
, 这个mobile__contains
千万不能写错, 下划线_是两个, 不能漏写也不能多写, 这个是按照手机号来查询数据。然后 再用assets_list = models.Assets.objects.filter(**dict_data)
这行代码, 将我想要查询的数据查询出来, 注意在filter里面要用**dict_data
, 因为dict_data是个字典。
二、实现翻页功能
我们在bootstrap里面找到分页的代码:

将它复制黏贴到代码里面:
assets.html:
html
{% extends "index/model_tmp.html" %}
{% block content %}
<div class="container">
<a href="/assets/add/" class="btn btn-success">添加信息</a>
{# 实现搜素查询 #}
<div style="float: right">
<form method="get">
<div class="input-group" style="float: right;width: 300px;">
<input type="text" class="form-control" name="search" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">搜索</button>
</span>
</div>
</form>
</div>
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">资产表</h3>
</div>
<div class="panel-body">
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>手机号</th>
<th>状态</th>
<th>创建时间</th>
<th>使用者</th>
<th>价格</th>
</tr>
</thead>
<tbody>
{% for data in assets_list %}
<tr>
<th scope="row">{{ data.id }}</th>
<td>{{ data.mobile }}</td>
{% if data.status == 1 %}
<td style="color: green">{{ data.get_status_display }}</td>
{% else %}
<td style="color: red">{{ data.get_status_display }}</td>
{% endif %}
<td>{{ data.create_time|date:"Y-m-d" }}</td>
<td>{{ data.user.name }}</td>
<td>{{ data.price }}</td>
<td style="color: green">
<a href="/assets/{{ data.id }}/modify"><span style="color: green;"
class="glyphicon glyphicon-pencil"
aria-hidden="true"></span></a>
<a href="/assets/{{ data.id }}/del/"><span style="color: red;"
class="glyphicon glyphicon-trash"
aria-hidden="true"></span></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{# 实现分页查询 #}
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true"><<</span>
</a>
</li>
<li><a href="?page=1">1</a></li>
<li><a href="?page=2">2</a></li>
<li><a href="?page=3">3</a></li>
<li><a href="?page=4">4</a></li>
<li><a href="?page=5">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">>></span>
</a>
</li>
</ul>
</div>
{% endblock %}
python
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.shortcuts import render, redirect
from django.utils.safestring import mark_safe
from django import forms
from project_one import models
# Create your views here.
def assets(request):
# assets_list = models.Assets.objects.all()
# 搜索信息
dict_data = {}
# 获取搜素框里的内容, 就是获取网址里面的search参数的值
value = request.GET.get('search')
if value:
# 在表格中搜素包含输入框当中的数据, 这里搜素的是手机号, key为mobile__contains
dict_data["mobile__contains"] = value
# assets_list = models.Assets.objects.filter(**dict_data)
# 获取分页组件里面选中的页码, 也是获取网址里面的page参数的值
page = int(request.GET.get('page', 1))
# 每一页查询10条数据
page_size = 10
# 当前页开始的数据
start = (page - 1) * page_size
# 当前页结尾的数据
end = page_size * page
# 利用切片, 实现分页查询, 查询出当页数据
assets_list = models.Assets.objects.filter(**dict_data)[start:end]
return render(request, "assets/assets_list.html", {"assets_list": assets_list})
运行结果:
我们会发现, 当我们点击第一页的时候, 就给我们展示第一页的数据

点击第几页, 就给我们展示第几页的数据。
但是光这五页数据, 肯定是不够的。当我们数据量大的时候, 需要几十页甚至于上百页上千页数据。
不过这又出现了一个问题, 如果有上百页上千页数据的话, 难道我们需要在分页组件里写上百条上千条li和a吗?这样显然不可行, 所以我们可以统一写五个带有页码的按钮, 但是这五个按钮, 页码会变化。
假如我们有20页数据要展示:
当我们点击1到3页的时候, 这五个按钮依然显示1, 2, 3, 4, 5, 但是当我们点击4的时候, 这五个按钮就要显示2, 3, 4, 5, 6了, 后面以此类推, 当我们点击18, 19或者20的时候, 这五个按钮显示16, 17, 18, 19, 20。我们可以发现一个规律, 就是我们选中的页数, 除了1, 2, 3, 18, 19, 20以外, 其他所有我们选中的页码, 离最左边和最右边的页码始终相差2。而页码最前面只有点击到4的时候, 五个按钮里面的页码才会开始发生变化, 页码最后面只有到18开始, 页码才不会变化。
我们可以设plus=2, 这个2指的是我们选中的页码, 离最左边和最右边的页码始终相差2。开始页用start_page, 结束页用end_page。
代码:
assets.py部分代码:
python
# 统计表当中的总个数
data_asset_count = models.Assets.objects.filter(**dict_data).count()
# 求得表中的总个数都需要多少页来展示, page_num代表总页数, div代表剩余的数据还有多少条
page_count, div = divmod(data_asset_count, page_size)
if div:
page_count += 1
# 我们需要在分页组件里面展示五个页码。
# 当我们选中的页数, 和最左边最右边显示的页数相差2, 所以我们将plus设置为2, 比如我选择第三页, 那最左边显示的页码是1最右边显示的页码是5。
plus = 2
# 我们想要分页功能, 展示其中5个页码, 如果想要展示不同个页数的页码, 自己可以调整。
# 当总页数不超过5页的时候, 1 + 2 * plus意思是当前选择的页, 加上左边还有两页, 右边也还有两页, 总共是5页。
if data_asset_count <= 1 + 2 * plus:
# 开始页数为1
start_page = 1
# 结束位置就是总页数
end_page = data_asset_count
# 这里面全是总页数大于5页的情况
else:
# 如果我目前选择的页码, 小于等于3
if page <= plus + 1:
# 开始页还是1
start_page = 1
# 结束页是5, 1 + 2 * plus这个意思上面有注释。
end_page = 1 + 2 * plus
# 如果我目前选择的页码加上2能够大于总页数, 那就说明分页组件里面的页码是最后五页数据了, 比如总页数为20, 我选择的是第19页, 19+2=21>20
elif page + plus > page_count: # 这里写>=也可以
# 开始页为总页数减去两倍的plus, 比如总共有20页, 当我们分页组件显示的页码是最后五页的时候, 最左边应该显示的是16。所以正好是总页数-两倍的plus
start_page = page_count - 2 * plus
# 结尾页展示的就是总页数
end_page = page_count
# 如果我们目前选择的页码就在正中间, 排除1, 2, 3, 19, 20页的其它所有页数。
else:
# 开始页数就是当前分页组件选择的页数-plus
start_page = page - plus
# 结束页数就是当前分页组件选择的页数+plus
end_page = page + plus
然后我们需要实现动态添加html代码:
python
# 创建一个列表, 用于存储html代码, 以字符串来保存到列表中
html_list = []
# 分页组件返回到首页功能
html_list.append(f"""<li><a href="?page=1">首页</a></li>""")
# 如果当前选择的页码>1, 可以往前退一页, 否则不能在往前退了。在li标签上加class="disabled"代表禁用
if page > 1:
html_list.append(f"""<li><a href="?page={page - 1}"><span aria-hidden="true"><<</span></a></li>""")
else:
html_list.append("""<li class="disabled"><span
aria-hidden="true"><<</span></li>""")
# 分页组件的中间翻页的内容, 点击第几页就到第几页, 在分页组件当中, 选中的页码会有背景色。li标签里面的class='active'代表选中了那个页码, 会出现背景色
for page_num in range(start_page, end_page + 1):
if page_num == page:
html_list.append(f"<li class='active'><a href='?page={page_num}'>{page_num}</a></li>")
else:
html_list.append(f"<li><a href='?page={page_num}'>{page_num}</a></li>")
# 如果当前选择的页码<总页数, 可以往前进一页, 否则不能在往进退了。在li标签上加class="disabled"代表禁用
if page < page_count:
html_list.append(f"""<li><a href="?page={page + 1}"><span aria-hidden="true">>></span></a></li>""")
else:
html_list.append("""<li class="disabled"><span
aria-hidden="true">>></span></li>""")
# 分页组件进入到尾页功能
html_list.append(f"""<li><a href="?page={page_count}">尾页</a></li>""")
# join就是将列表当中所有的内容全部拼接在一起为字符串。mark_safe函数的作用是将字符串里面的内容, 转换为html元素。
# mark_safe也是django框架里面的函数, 需要手动导入, 导入语句为from django.utils.safestring import mark_safe
page_string = mark_safe("".join(html_list))
最后不要忘记return了。
python
# 不能忘记将page_string传给前端。
return render(request, "assets/assets_list.html", {"assets_list": assets_list})
完整代码:
python
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.shortcuts import render, redirect
from django.utils.safestring import mark_safe
from django import forms
from project_one import models
# Create your views here.
def assets(request):
# assets_list = models.Assets.objects.all()
# 搜索信息
dict_data = {}
# 获取搜素框里的内容, 就是获取网址里面的search参数的值
value = request.GET.get('search')
if value:
# 在表格中搜素包含输入框当中的数据, 这里搜素的是手机号, key为mobile__contains
dict_data["mobile__contains"] = value
# assets_list = models.Assets.objects.filter(**dict_data)
# 获取分页组件里面选中的页码, 也是获取网址里面的page参数的值
page = int(request.GET.get('page', 1))
# 每一页查询10条数据
page_size = 10
# 当前页开始的数据
start = (page - 1) * page_size
# 当前页结尾的数据
end = page_size * page
# 利用切片, 实现分页查询, 查询出当页数据
assets_list = models.Assets.objects.filter(**dict_data)[start:end]
# 统计表当中的总个数
data_asset_count = models.Assets.objects.filter(**dict_data).count()
# 求得表中的总个数都需要多少页来展示, page_num代表总页数, div代表剩余的数据还有多少条
page_count, div = divmod(data_asset_count, page_size)
if div:
page_count += 1
# 我们需要在分页组件里面展示五个页码。
# 当我们选中的页数, 和最左边最右边显示的页数相差2, 所以我们将plus设置为2, 比如我选择第三页, 那最左边显示的页码是1最右边显示的页码是5。
plus = 2
# 我们想要分页功能, 展示其中5个页码, 如果想要展示不同个页数的页码, 自己可以调整。
# 当总页数不超过5页的时候, 1 + 2 * plus意思是当前选择的页, 加上左边还有两页, 右边也还有两页, 总共是5页。
if data_asset_count <= 1 + 2 * plus:
# 开始页数为1
start_page = 1
# 结束位置就是总页数
end_page = data_asset_count
# 这里面全是总页数大于5页的情况
else:
# 如果我目前选择的页码, 小于等于3
if page <= plus + 1:
# 开始页还是1
start_page = 1
# 结束页是5, 1 + 2 * plus这个意思上面有注释。
end_page = 1 + 2 * plus
# 如果我目前选择的页码加上2能够大于总页数, 那就说明分页组件里面的页码是最后五页数据了, 比如总页数为20, 我选择的是第19页, 19+2=21>20
elif page + plus > page_count: # 这里写>=也可以
# 开始页为总页数减去两倍的plus, 比如总共有20页, 当我们分页组件显示的页码是最后五页的时候, 最左边应该显示的是16。所以正好是总页数-两倍的plus
start_page = page_count - 2 * plus
# 结尾页展示的就是总页数
end_page = page_count
# 如果我们目前选择的页码就在正中间, 排除1, 2, 3, 19, 20页的其它所有页数。
else:
# 开始页数就是当前分页组件选择的页数-plus
start_page = page - plus
# 结束页数就是当前分页组件选择的页数+plus
end_page = page + plus
# 创建一个列表, 用于存储html代码, 以字符串来保存到列表中
html_list = []
# 分页组件返回到首页功能
html_list.append(f"""<li><a href="?page=1">首页</a></li>""")
# 如果当前选择的页码>1, 可以往前退一页, 否则不能在往前退了。在li标签上加class="disabled"代表禁用
if page > 1:
html_list.append(f"""<li><a href="?page={page - 1}"><span aria-hidden="true"><<</span></a></li>""")
else:
html_list.append("""<li class="disabled"><span
aria-hidden="true"><<</span></li>""")
# 分页组件的中间翻页的内容, 点击第几页就到第几页, 在分页组件当中, 选中的页码会有背景色。li标签里面的class='active'代表选中了那个页码, 会出现背景色
for page_num in range(start_page, end_page + 1):
if page_num == page:
html_list.append(f"<li class='active'><a href='?page={page_num}'>{page_num}</a></li>")
else:
html_list.append(f"<li><a href='?page={page_num}'>{page_num}</a></li>")
# 如果当前选择的页码<总页数, 可以往前进一页, 否则不能在往进退了。在li标签上加class="disabled"代表禁用
if page < page_count:
html_list.append(f"""<li><a href="?page={page + 1}"><span aria-hidden="true">>></span></a></li>""")
else:
html_list.append("""<li class="disabled"><span
aria-hidden="true">>></span></li>""")
# 分页组件进入到尾页功能
html_list.append(f"""<li><a href="?page={page_count}">尾页</a></li>""")
# join就是将列表当中所有的内容全部拼接在一起为字符串。mark_safe函数的作用是将字符串里面的内容, 转换为html元素。
# mark_safe也是django框架里面的函数, 需要手动导入, 导入语句为from django.utils.safestring import mark_safe
page_string = mark_safe("".join(html_list))
# 不能忘记将page_string传给前端。
return render(request, "assets/assets_list.html", {"assets_list": assets_list, "page_string": page_string})
这里代码比较长, 但每一行代码都有注释, 大家慢慢看, 慢慢学, 其实逻辑上不是很困难, 但是代码量比较大, 处理的过程比较复杂。
运行结果:
默认是第一页的数据

然后我们点击第三页:

点击第四页:

往后翻页, 直到点击第13页:

往后翻页, 直到点击第18页:

第19页:

第20页:

点击首页:

它帮我们跳转到了第一页。
点击尾页:

它帮我们跳转到了最后一页。点击左边的<<按钮:

点击一下, 页数往回退一页。
直到退到第一页, 就不能在往回退数据了。
如图:

鼠标放到<<上面的时候, 有个红色圈代表禁止使用那个按钮。
>>
也是一个道理, 也是每点击一次网后面翻一页, 直到翻到最后一页, 鼠标放到>>
上面的时候, 有个红色圈代表禁止使用那个按钮。同样也不能继续往后翻页了。
好了, 这就是我们这篇文章的搜索和翻页功能了!!!
以上就是Django数据的翻页和搜索功能的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!
如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.
学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.
人生路漫漫, 白鹭常相伴!!!