day68---django框架学习初阶(九)

自定义分页器的实现

前言

django也有自带额分页器,但是功能较少,使用起来较为繁琐。所以我们可以使用自定义非分页器。

自定义分页器的推导思路

# queryset对象是支持索引切片操作的(不支持负数索引)
book_queryset=models.Book.objects.all()
page_queryset=book_queryset[page_obj.start:page_obj.end]

# 如何获取用户访问的页数?
get请求是可以携带参数:url?page
默认显示的是第一页:current_page=request.GET.get("page",1) 
"page"参数非法,则显示默认的第一页

# 设定每页的展示的记录数?
per_page_num=10

# 切片的起始位置和结束位置
start_page=(current_page-1)*10
end_page=current_page*10

# 获取展示数据的总条数
record_count=book_queryset.count() //通过queryset对象的count方法获取数据库数据的总条数

# 确定总的数据需要多少页才能展示
内置方法divmod()
base_page,is_carry=divmod(record_count,per_page_num)

# 前端模板语法没有range功能
前端代码后端书写,写完传给前端

# 针对展示页码的需要自己规划好到底展示多少个页码
一般情况下页码的个数设计都是奇数(符合审美标准)  11个页码
当前页减5
当前页加6
你可以给标签价样式从而让选中的页码高亮显示

# 针对页码小于6的情况 你需要做处理 不能再减

思路有了,那就撸起袖子写吧。

封装好的代码

"""
自定义分页器代码
"""
class Pager(object):
    def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
        """
        封装分页相关数据
        :param current_page: 当前页
        :param all_count:    数据库中的数据总条数
        :param per_page_num: 每页显示的数据条数
        :param pager_count:  最多显示的页码个数
        """
        try:
            current_page = int(current_page)
        except Exception as e:
            current_page = 1

        if current_page < 1:
            current_page = 1

        self.current_page = current_page

        self.all_count = all_count
        self.per_page_num = per_page_num

        # 总页码
        all_pager, tmp = divmod(all_count, per_page_num)
        if tmp:
            all_pager += 1
        self.all_pager = all_pager

        self.pager_count = pager_count
        self.pager_count_half = int((pager_count - 1) / 2)

    @property
    def start(self):
        return (self.current_page - 1) * self.per_page_num

    @property
    def end(self):
        return self.current_page * self.per_page_num

    def page_html(self):
        # 如果总页码 < 11个:
        if self.all_pager <= self.pager_count:
            pager_start = 1
            pager_end = self.all_pager + 1
        # 总页码  > 11
        else:
            # 当前页如果<=页面上最多显示11/2个页码
            if self.current_page <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page + self.pager_count_half) > self.all_pager:
                    pager_end = self.all_pager + 1
                    pager_start = self.all_pager - self.pager_count + 1
                else:
                    pager_start = self.current_page - self.pager_count_half
                    pager_end = self.current_page + self.pager_count_half + 1

        page_html_list = []
        # 添加前面的nav和ul标签
        page_html_list.append('''
                    <nav aria-label='Page navigation>'
                    <ul class='pagination'>
                ''')
        first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)

        if self.current_page >= self.all_pager:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
        page_html_list.append(last_page)
        # 尾部添加标签
        page_html_list.append('''
                                           </nav>
                                           </ul>
                                       ''')
        return ''.join(page_html_list)

使用

注意:

"""
当我们需要使用到非django内置的第三方功能或者组件代码的时候,一般情况下会创建一个名为utils文件夹,在该文件夹内对模块进行功能性划分,utils可以在每个应用下创建,需要具体结合实际情况。

我们自定义的分页器是基于bootstrap样式来的,所以你需要提前导入bootstrap:
(1)bootstrap 版本 v3
(2)jQuery 版本 v3
"""
└── utils
    ├── pager.py
    └── __pycache__
        └── pager.cpython-38.pyc

django后端:

class Book(View):
    def get(self, request, phone):
        user_obj = models.User.objects.filter(phone=phone).first()
        book_list = models.Book.objects.all()
        current_page = request.GET.get("page", 1)
        record_count = book_list.count()
        page_obj = pager.Pager(current_page, record_count, per_page_num=7, pager_count=11)
        page_queryset = book_list[page_obj.start:page_obj.end]
        return render(request, 'book.html',
                      {'user': user_obj, 'page': page_obj, 'page_queryset': page_queryset})

前端:

   <div class="col-lg-6">
                    <div class="input-group">
                        <input type="text" class="form-control" placeholder="书名~">
                        <span class="input-group-btn">
                            <button class="btn btn-success" type="button">搜索~</button>
                        </span>
                    </div><!-- /input-group -->
                </div>
                <div class="col-lg-6 text-right">
                    <a href="{% url 'app01:book_add' user.phone %}" class="btn btn-success">添加书籍</a>
                </div><br><br><br>
                <div class="col-lg-10 col-lg-offset-1">
                    <table class="table table-bordered table-striped table-hover">
                        <thead>
                        <tr>
                            <th class="text-center thead-style">序号</th>
                            <th class="text-center thead-style">书名</th>
                            <th class="text-center thead-style">价格(元)</th>
                            <th class="text-center thead-style">作者</th>
                            <th class="text-center thead-style">出版日期</th>
                            <th class="text-center thead-style">出版社</th>
                            <th class="text-center thead-style">操作</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for book in page_queryset %}
                            <tr>
                                <td class="text-center tbody-style">{{ page.start|add:forloop.counter }}</td>
                                <td>{{ book.name }}</td>
                                <td class="text-center">{{ book.price }}</td>
                                <td>
                                    {% for author in book.authors.all %}
                                        {% if forloop.last %}
                                            {{ author.name }}
                                        {% else %}
                                            {{ author.name }}|
                                        {% endif %}
                                    {% endfor %}
                                </td>
                                <td class="text-right">{{ book.publish_date|date:'Y/m/d' }}</td>
                                <td class="text-center">{{ book.publish.name }}</td>
                                <td class="text-center">
                                    <a href="{% url 'app01:book_edit' user.phone book.id %}"
                                       class="btn btn-primary btn-xs">编辑</a>
                                    <button class="btn btn-danger btn-xs del" delete_id="{{ book.pk }}">删除</button>
                                </td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                    <div class="text-center">
                        {{ page.page_html|safe }}
                    </div>
                </div>

效果展示

原文地址:https://www.cnblogs.com/surpass123/p/13043320.html