Django项目实战(一):图书管理系统---第六阶段---添加自定义分页

下面是小凰凰的简介,看下吧!
人生态度:珍惜时间,渴望学习,热爱音乐,把握命运,享受生活
学习技能:网络 -> 云计算运维 -> python全栈( 当前正在学习中)
您的点赞、收藏、关注是对博主创作的最大鼓励,在此谢过!
有相关技能问题可以写在下方评论区,我们一起学习,一起进步。
后期会不断更新python全栈学习笔记,秉着质量博文为原则,写好每一篇博文。

文章目录

    • 一、效果展示
    • 二、pager.py
    • 三、views.py
    • 四、urls.py
    • 五、index.html
        • 1、完整修改后的文件
        • 2、主要修改点说明

django有带分页器,也可以针对其进行扩展分页,但是我比较推崇自己自定义分页,这个东西到那个语言都能行!

和分页有关的文件如下:
Django项目实战(一):图书管理系统---第六阶段---添加自定义分页_第1张图片

一、效果展示

二、pager.py

class Pagination(object):
    def __init__(self, total_count, current_page, per_page_item_num=10, max_page_num=7):
        # 数据总个数
        self.total_count = total_count
        # 当前页
        try:
            v = int(current_page)
            if v <= 0:
                v = 1
            self.current_page = v
        except Exception as e:
            self.current_page = 1
        # 每页显示的行数
        self.per_page_item_num = per_page_item_num
        # 最多显示页数
        self.max_page_num = max_page_num

    def start(self):
        return (self.current_page - 1) * self.per_page_item_num

    def end(self):
        return self.current_page * self.per_page_item_num

    @property
    def num_pages(self):
        """
        总页数
        :return:
        """
        # 666
        # 10
        a, b = divmod(self.total_count, self.per_page_item_num)
        if b == 0:
            return a
        return a + 1

    def pager_num_range(self):
        # self.num_pages()
        # self.num_pages
        # 当前页
        # self.current_page
        # 最多显示的页码数量 11
        # self.per_pager_num
        # 总页数
        # self.num_pages
        if self.num_pages < self.max_page_num:
            return range(1, self.num_pages + 1)
        # 总页数特别多 5
        part = int(self.max_page_num / 2)
        if self.current_page <= part:
            return range(1, self.max_page_num + 1)
        if (self.current_page + part) > self.num_pages:
            return range(self.num_pages - self.max_page_num + 1, self.num_pages + 1)
        return range(self.current_page - part, self.current_page + part + 1)

    def page_str(self):
        page_list = []

        first = "
  • 首页
  • "
    page_list.append(first) if self.current_page == 1: prev = "
  • 上一页
  • "
    else: prev = "
  • 上一页
  • "
    % (self.current_page - 1,) page_list.append(prev) for i in self.pager_num_range(): if i == self.current_page: temp = "
  • %s
  • "
    % (i, i) else: temp = "
  • %s
  • "
    % (i, i) page_list.append(temp) if self.current_page == self.num_pages: nex = "
  • 下一页
  • "
    else: nex = "
  • 下一页
  • "
    % (self.current_page + 1,) page_list.append(nex) last = "
  • 尾页
  • "
    % (self.num_pages,) page_list.append(last) return ''.join(page_list)

    这个文件就是分页用的,以后我们哪个python项目要用分页直接把这个放进去就行!

    三、views.py

    上面这个Pagination类怎么用呢?在哪里用呢?
    在views.py里用,用法如下:

    @transaction.atomic
    def book_view(request):
        from app01.pager import Pagination
        total_count = Book.objects.all().count()
        current_page = request.GET.get('page')
        page_obj = Pagination(total_count, current_page, max_page_num=11)
        book_list = Book.objects.all()[page_obj.start(): page_obj.end()]
        start = page_obj.start() + 1
        for book_obj in book_list:  # 把书籍编号放进对象中,方便前端取
            book_obj.nid = start
            start += 1
        return render(request, 'index.html', {
         'book_list': book_list, 'page_obj': page_obj, 'username':request.user})
    

    只需要把book_view视图函数一改就行!

    四、urls.py

    path('', views.book_view, name='book_view'),
    

    和分页有关的就这一个路由!

    Pagination类中有这么一个函数,如果你的路由不是主页,而是其他如:

    path('index/', views.book_view, name='book_view'),
    

    那么你需要改这个函数,如下:

        def page_str(self):
            page_list = []
    
            first = "
  • 首页
  • "
    page_list.append(first) if self.current_page == 1: prev = "
  • 上一页
  • "
    else: prev = "
  • 上一页
  • "
    % (self.current_page - 1,) page_list.append(prev) for i in self.pager_num_range(): if i == self.current_page: temp = "
  • %s
  • "
    % (i, i) else: temp = "
  • %s
  • "
    % (i, i) page_list.append(temp) if self.current_page == self.num_pages: nex = "
  • 下一页
  • "
    else: nex = "
  • 下一页
  • "
    % (self.current_page + 1,) page_list.append(nex) last = "
  • 尾页
  • "
    % (self.num_pages,) page_list.append(last) return ''.join(page_list)

    你需要把里面的href都改了,改成href='/index/?page=%s'

    五、index.html

    1、完整修改后的文件

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        {
         % block page_title %}
            <title>图书管理系统</title>
        {
         % endblock %}
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
        <style>
            .table_area {
         
                width: 800px;
                position: absolute;
                top: 150px;
                left: 250px;
            }
    
            .add_btn {
         
                font-size: 18px;
                font-family: "Kaiti SC";
                font-weight: bolder;
            }
    
            .sys-menu {
         
                position: relative;
                top: auto;
                left: 35px;
                width: 150px;
                height: 200px;
            }
    
            .page_top {
         
                background-color: #146896;
                width: 100%;
                height: 50px;
            }
    
            .panel-heading {
         
                text-align: center;
                font-weight: bolder;
            }
    
            .panel-body {
         
                text-align: center;
                width: 100%;
            }
    
            .panel-body > a {
         
                text-decoration: none;
            }
    
            .panel-body > a:hover {
         
                color: skyblue;
            }
    
            .active {
         
                background-color: blanchedalmond;
            }
    
            #exampleModalLabel {
         
                font-family: "Kaiti SC";
                font-size: 20px;
                font-weight: bolder;
            }
    
            .login-area {
         
                margin-right: 20px;
            }
    
            .modify-key, .login_out, .user-name, .head-img {
         
                float: right;
                color: skyblue;
                margin-right: 15px;
            }
    
            .modify-key:hover, .login_out:hover {
         
                color: red;
                text-decoration: none;
                cursor: pointer;
            }
    
            .page_top > div {
         
                position: relative;
                top: 15px;
            }
    
            .head-img {
         
                width: 45px;
                height: 45px;
                border-radius: 45px;
                overflow: hidden;
                position: relative;
                top: -12px;
                border: 2px solid white;
            }
    
            .user-name {
         
                font-family: "Kaiti SC";
                font-weight: bolder;
            }
    
            .head-img > img {
         
                width: 100%;
            }
    
            #warning-key {
         
                color: red;
                font-family: "Kaiti SC";
            }
    
            .split_page_area {
         
                line-height: 100%;
                text-align: center;
                margin-top: -30px;
                margin-bottom: -30px;
            }
        </style>
    </head>
    <body>
    <div class="page_top">
        <div class="login-area">
            <a type="button" class=" modify-key" data-toggle="modal" data-target="#exampleModal"
               data-whatever="@mdo">修改密码
            </a>
    
            <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                                    aria-hidden="true">&times;</span></button>
                            <h4 class="modal-title" id="exampleModalLabel">密码修改</h4>
                        </div>
                        <div class="modal-body">
                            <form>
                                <div class="form-group">
                                    <label for="old_secret" class="control-label">原密码</label>
                                    <input type="password" class="form-control" id="old_secret">
                                </div>
                                <div class="form-group">
                                    <label for="new_secret" class="control-label">新密码</label>
                                    <input type="password" class="form-control" id="new_secret">
                                </div>
                                <div class="form-group">
                                    <label for="re_new_secret" class="control-label">
                                        确认新密码&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span id="warning-key"></span>
                                    </label>
                                    <input type="password" class="form-control" id="re_new_secret">
                                </div>
                                <div class="modal-footer">
                                    <button id="sub-mdkey" type="button" class="btn btn-primary login-btn"
                                            data-dismiss="modal">提交
                                    </button>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
            <a class="login_out" href="{% url 'login_out' %}">注销</a>
            <span class="user-name">{
         {
          username }}</span>
            <div class="head-img">
                <img src="http://127.0.0.1:8000/static/img/head-img.jpg" alt="">
            </div>
        </div>
    </div>
    
    <div class="panel panel-default sys-menu">
        <div class="panel-heading">
            功能系统
        </div>
        {
         % block sys_view %}
            <div class="panel-body active">
                <a href="{% url 'book_view' %}">图书管理系统</a>
            </div>
            <div class="panel-body">
                <a href="{% url 'author_view' %}">作者管理系统</a>
            </div>
            <div class="panel-body">
                <a href="{% url 'publisher_view' %}">出版社管理系统</a>
            </div>
        {
         % endblock %}
    </div>
    
    {
         % block master_content %}
        <div class="table_area">
            {
         % csrf_token %}
            <table class="table table-hover">
                <thead>
                <tr>
                    <th>书籍编号</th>
                    <th>书名</th>
                    <th>价格</th>
                    <th>出版时间</th>
                    <th>出版社</th>
                    <th>作者</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                {
         % for book_obj in book_list %}
                    <tr>
                        <td>{
         {
          book_obj.nid }}</td>
                        <td>{
         {
          book_obj.name }}</td>
                        <td>{
         {
          book_obj.price }}</td>
                        <td>{
         {
          book_obj.pub_date|date:'Y-m-d' }}</td>
                        <td>{
         {
          book_obj.publish.name }}</td>
                        <td>
                            {
         % for author_obj in book_obj.authors.all %} <!--book_obj.authors.all得到的是一个作者对象的queryset-->
                                {
         % if forloop.last %}
                                    <!--
                                        有人会问这里不是对象吗?为什么打印对象?不应该是author_obj.name吗?
                                        我在model中写了双下方法str-->
                                    {
         {
          author_obj }}
                                {
         % else %}
                                    {
         {
          author_obj }},
                                {
         % endif %}
    
                            {
         % endfor %}
                        </td>
                        <td>
                            <a href="{% url 'book_edit' book_obj.pk %}" class="btn btn-warning btn-xs">编辑</a>
                            <!-- 删除我们应该使用ajax进行局部刷新,不应该和编辑一样使用页面刷新 -->
                            <a id="del_book" class="btn btn-danger btn-xs" book_id={
         {
          book_obj.pk }}>删除</a>
                        </td>
                    </tr>
                    {
         % if forloop.last and forloop.counter > 0 %}
                        <tr>
                            <td colspan="7">
                                <div class="split_page_area">
                                    <ul class="pagination pagination-md">
                                        {
         {
          page_obj.page_str|safe }}
                                    </ul>
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td colspan="7">
                                <a href="{% url 'book_add' %}" class="btn btn-info btn-xs form-control add_btn">添加书籍</a>
                            </td>
                        </tr>
                    {
         % endif %}
                {
         % empty %}
                    <tr align="center">
                        <td colspan="7">
                            暂未上架任何书籍... <br>
                            <span>请点击:<a href="{% url 'book_add' %}" class="btn btn-info btn-xs">添加书籍</a></span>
                        </td>
                    </tr>
                {
         % endfor %}
                </tbody>
            </table>
    
        </div>
    {
         % endblock %}
    
    </body>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
    {
         % block script_area %}
        <script>
            $(function () {
         
                $("tbody").on('click', '#del_book', function () {
         
                    let $ele = $(this).parent().parent()
                    $.ajax({
         
                        url: `/books/del/${
         $(this).attr('book_id')}/`,
                        type: "post",
                        data: {
         
                            csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val()
                        },
                        success: function (response) {
         
                            response = JSON.parse(response)
                            if (response["status"] == true) {
         
                                $ele.remove()
                            } else {
         
                                alert('书籍删除失败!请重试')
                            }
                        }
                    })
                })
                $('#re_new_secret').blur(function () {
         
                    let re_val = $(this).val()
                    let val = $('#new_secret').val()
                    if (re_val != val) {
         
                        $('#warning-key').text('两次密码输入不一致,请重新输入')
                        setTimeout(function () {
         
                            $('#warning-key').text('')
                        }, 3000)
                    }
                })
                $('.login-btn').click(function () {
         
                    $.ajax({
         
                        url: '{% url 'secret_modify' %}',
                        type: 'post',
                        data: {
         
                            old_secret: $('#old_secret').val(),
                            new_secret: $('#new_secret').val()
                        },
                        success: function (response) {
         
                            if (response == 'ok') {
         
                                alert('密码修改成功!')
                                setTimeout(function () {
         
                                    location.href = "{% url 'login_view' %}"
                                }, 3000)
                            } else {
         
                                alert('密码修改失败!')
                            }
                        }
                    })
                })
            })
        </script>
    {
         % endblock %}
    </html>
    

    2、主要修改点说明

    {
         % for book_obj in book_list %}
                    <tr>
                    # 书籍编号采用新加的nid,使得即使分页,每页之间编号都是连续的!
                        <td>{
         {
          book_obj.nid }}</td> 
                    </tr>
                    {
         % if forloop.last and forloop.counter > 0 %}
                        <tr>
                            <td colspan="7">
                       
                                <div class="split_page_area">
                                # 这里就是核心的分页器,外层div主要起个布局定位作用
                                    <ul class="pagination pagination-md">
                                        {
         {
          page_obj.page_str|safe }}
                                    </ul>
                                    
                                </div>
                                
                            </td>
                        </tr>
                        <tr>
                            <td colspan="7">
                                <a href="{% url 'book_add' %}" class="btn btn-info btn-xs form-control add_btn">添加书籍</a>
                            </td>
                        </tr>
                    {
         % endif %}
    

    你可能感兴趣的:(#,Web框架,django)