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

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

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

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

相关推荐
雷渊11 分钟前
库存系统如何避免超卖和少卖?
后端
一个小坑货16 分钟前
Docker 部署 MySQL 数据库
数据库·mysql·docker
PythonicCC20 分钟前
基于Python Socket的多线程聊天程序案例分析
python
电商api接口开发22 分钟前
ASP.NET MVC 实现增删改查(CRUD)操作的完整示例
后端·asp.net·mvc
曾经的三心草37 分钟前
博客系统-邮件发送-nginx-服务部署
java·数据库·nginx·邮件发送·服务部署
Dxy123931021637 分钟前
NLTK 语料库与词典资源
python
Java中文社群43 分钟前
聊聊SpringAI流式输出的底层实现?
java·人工智能·后端
雷渊1 小时前
如何设计一个订单号生成服务?
后端
站大爷IP1 小时前
Python中main函数:代码结构的基石
python