美文网首页
Django自定义分页功能的实现

Django自定义分页功能的实现

作者: 金融测试民工 | 来源:发表于2020-11-28 16:35 被阅读0次

    前言:本文介绍在Django中如何通过前后端代码实现页面自定义分页功能,详细介绍实现原理,并附实现代码。

    实现的功能:

    1、根据页数,显示分页标签,并限制显示的分页标签最多10个

    2、当前页标签颜色高亮,当页数标签多于10个时位于分页标签的中间处

    3、实现上一页、下一页、首页、尾页标签功能

    4、具有跳转到指定页面功能,按enter或者点击按钮跳转

    5、每页显示的行数可定制,行数修改后页数也跟着变更,每页显示行数使用cookie来保存


    实现的原理:

    1、分页标签先在后台组装好(这里使用a标签),可以页数几个就组装几个分页标签,然后由Django插入到前端的HTML代码中统一发给请求端。

    2、当前页标签高亮功能:首先需要知道用户当前页是哪,这从客户端发送过来的请求数据里取得,然后在组装当前页标签内容时,加上特殊的CSS样式,返回给用户,这样在前端看到的当前页标签样式就和其他不同。

    3、当前页标签居中:我们这边限制最多只显示10个标签,后台组装页码标签,一般从(当前页码-4)到(当前页码+5)。特殊情况该功能不起作用,例如1、总页数小于等于10页;2、当前页小于5;3、当前页大于总页数-5。

    4、每页显示的行数定制功能:首次请求,默认10行,保存在cookie中。点击修改行数自动触发事件,修改客户端中保存行数信息的cookie值,并刷新页面。服务端在收到客户端发送过来信息中,从cookie中取得行数定制信息,按该行数组装分页标签,再返回给前端。


    用到的知识点:

    后端

    1、request.COOKIES.get(key):取得cookie值,设置cookie:HttpResponse/redirect/render().set_cookie.(k,v,...)

    2、render(request, 'URL', {k,v}):返回给前端,可以带参数

    3、locals():返回当前所有的本地变量字典,存在部分是django模板用不到变量

    3、mark_safe:转义,将HTML代码给转换成HTML实体,否则Django插入前端显示的是“HTML代码”

    前端

    1、获取cookie:$.cookie(k),设置cookie:$.cookie(k,v,{'path':value})

    2、刷新页面location.reload(),跳转到指定页面location.href=url

    3、$('XX').bind('keypress', function (event){}):绑定事件band,键盘输入事件keypress,键盘输入值event.keyCode,13为enter

    4、$('XX').change(function (){}):change有变动自动触发事件,这边用在修改页面显示行数

    5、{{ xxx|safe }}:|,过滤器,safe,将HTML代码给转换成HTML实体,防止XXS攻击,功能后后端的mark_safe相同

    后端代码:

    def query(request):

    """

    current_page:当前页码,默认第一页

    line_num:每页显示的行数,默认10行

    table_line_count:总行数

    page_count:总页数

    display_page_num_count:显示的页数码标签总个数,默认10个

    """

        current_page = int(request.GET.get('p',1))

        line_num = int(request.COOKIES.get("per_page_line_num",10))

        table_line_count=tablename.objects.count()            ####统计表总行数,tablename指数据库中的表,根据实际修改

    display_page_num_count=10

        ####求总页数

        a,b=divmod(table_line_count,line_num)      ####求除数和余数,例如divmod(5,1)=(1,1)

        if b>0:

            page_count=a+1

        else:

            page_count = a

    """

    first_page:首页

        last_page:尾页

        prev_page:上一页

        next_page:下一页

    first_display_page_num:第一个显示的页码

    last_display_page_num:最后一个显示的页码

    """

        first_page = "<a href='/query/?p=%s'>%s</a>" % (1, "首页")

        last_page = "<a href='/query/?p=%s'>%s</a>" % (page_count, "尾页")

        if current_page-1==0:

            prev_page="<a href='/query/?p=%s'>%s</a>" % (current_page, "上一页")

        else:

            prev_page="<a href='/query/?p=%s'>%s</a>" % (current_page-1, "上一页")

        if current_page==page_count:

            next_page="<a href='/query/?p=%s'>%s</a>" % (current_page, "下一页")

        else:

            next_page="<a href='/query/?p=%s'>%s</a>" % (current_page+1, "下一页")

        page_str=""

        page_str+=first_page

        page_str+=prev_page

        if page_count<=display_page_num_count:

            first_display_page_num = 1

            last_display_page_num = page_count + 1

        else:

            # 总页数大于10页(只显示10个页数标签)

            #    如果当前页数《=5

            #        显示1-10页数标签

            #    如果当前页数x》5

            #        显示 x-4到x+5页数标签

            #    如果当前页数x》总页数-5

            #        显示 总页数-9 到总页数之间的标签

            if current_page_num<=5:

                first_display_page_num=1

                last_display_page_num=display_page_num_count

            elif 5<current_page_num<=page_count-5:

                first_display_page_num=current_page_num-5+1

                last_display_page_num=current_page_num+5

            else:

                first_display_page_num=page_count-5-5+1

                last_display_page_num=page_count

        for i in range(first_display_page_num, last_display_page_num):

            if i == current_page:

                page_str += "<a class='active'  href='/query/?p=%s'>%s</a>" % (i, i)

            else:

                page_str += "<a href='/query/?p=%s'>%s</a>" % (i, i)

        page_str += next_page

        page_str += last_page

        page_str = mark_safe(page_str)

        response = render(request, 'query.html', locals())

        response.set_cookie("per_page_line_num",line_num,path='/query/')  ####设置每页显示的行数

        return response

    前端代码(query.html)

    <!DOCTYPE html>

    <html lang="en">

    <head>

        <meta charset="UTF-8">

        <title></title>

        <style>

            .pagination {

                display: inline-block;

                padding-left: 0;

                margin: 20px 0;

                border-radius: 4px;

            }

            .pagenumber {

                display: inline-block;

                padding-left: 0;

                margin: 20px 0;

                border-radius: 4px;

            }

            .pagenumber a {

                display: inline-block;

                padding: 5px;

                background-color: #9cc2cb;

            }

            .pagenumber a.active {

                background-color: brown;

                color: white;

            }

        </style>

    </head>

    <body>

    <label>共{{page_count}}页,{{table_line_count}}行,每页显示

        <select class="pagination" id="per_page_line_num">

            <option>10</option>

            <option>30</option>

            <option>50</option>

            <option>100</option>

        </select>

        条记录,</label>

    <label>前往

        <input type='text' style='width:36px'>页

        <input type='button' value='GO' onclick="jumpto(this,'/query/?p=')">

    </label>

    <div class="pagenumber">

        {{ page_str|safe }}

        <!--{{ page_str }}-->

    </div>

    <script>

        //设置页面显示的行数,每次访问都先从cookie中取得

        $(function () {

            var v = $.cookie('per_page_line_num');

            $('#per_page_line_num').val(v)

        });

        //修改页面显示行数

        $('#per_page_line_num').change(function () {

            var v = $('#per_page_line_num').val();

            $.cookie('per_page_line_num', v, {'path': '/query/'});

            console.log(v);

            location.reload();

        });

        //跳转到指定页面功能函数,鼠标点击按钮触发

        function jumpto(ths, url) {

            var v = $(ths).siblings().val();

            location.href = url + v;

        }

        //跳转到指定页面功能函数,enter触发

        //    $('label input[type=text]').keydown(function (event) {

        $('label input[type=text]').bind('keypress', function (event) {

            //  console.log($(this).val(), event.keyCode);

            if (event.keyCode == 13) {

                var v = $(this).val();

                var url = "/query/?p=";

                location.href = url + v;

            }

        });

    </script>

    </body>

    </html>

    是全页面刷新,且每页显示数量放在cookie里传给服务端,然后服务端再根据这信息编排页码标签返回给客户端。

    相关文章

      网友评论

          本文标题:Django自定义分页功能的实现

          本文链接:https://www.haomeiwen.com/subject/wvfcwktx.html