django之数据的翻页和搜索功能

数据的翻页和搜素功能

目录

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 %}

后端代码assets.py:

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 %}

后端assets.py:

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数据的翻页和搜索功能的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!

如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.

学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.

人生路漫漫, 白鹭常相伴!!!

相关推荐
别让别人觉得你做不到38 分钟前
Python(1) 做一个随机数的游戏
python
辛一一1 小时前
neo4j图数据库基本概念和向量使用
数据库·neo4j
小彭律师2 小时前
人脸识别门禁系统技术文档
python
巨龙之路2 小时前
什么是时序数据库?
数据库·时序数据库
蔡蓝2 小时前
binlog日志以及MySQL的数据同步
数据库·mysql
是店小二呀3 小时前
【金仓数据库征文】金融行业中的国产化数据库替代应用实践
数据库·金融·数据库平替用金仓·金仓数据库2025征文
炒空心菜菜3 小时前
SparkSQL 连接 MySQL 并添加新数据:实战指南
大数据·开发语言·数据库·后端·mysql·spark
张小九994 小时前
PyTorch的dataloader制作自定义数据集
人工智能·pytorch·python
专注于大数据技术栈4 小时前
Mac上安装Mysql的详细步骤及配置
mysql
zstar-_4 小时前
FreeTex v0.2.0:功能升级/支持Mac
人工智能·python·macos·llm