欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

Django 自定义分页

自定义分页

pages.py

import copy


class Pagination(object):
    def __init__(self, request, current_page_num, data_obj, per_page_num, pager_count=11):
        '''
        封装分页相关数据
     :param request: 用户请求体对象 :param current_page_num: 当前请求的页码 :param data_obj: 数据库中所查询记录的queryset :param per_page_num: 每页显示的数据条数 :param pager_count: 最多显示的页码个数
''' # 如果用户请求体中页码为非数字字符则返回第一页的数据 try: current_page_num = int(current_page_num) except ValueError: current_page_num = 1 # 请求页码小于1,返回第一页数据 if current_page_num < 1: current_page_num = 1 self.current_page_num = current_page_num self.data_obj = data_obj self.all_count = data_obj.count() self.per_page_num = per_page_num all_pager, tmp = divmod(self.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) self.request = request @property def start(self): return (self.current_page_num - 1) * self.per_page_num @property def end(self): return self.current_page_num * self.per_page_num # 给每条记录加上page_num编号 def insert_obj_num(self): self.data_obj = self.data_obj[self.start:self.end] page_num = list(range(self.start + 1, self.end + 1)) for i, el in enumerate(self.data_obj): el.page_num = page_num[i] # 保留搜索条件 def get_param(self, page_num): url_param = copy.deepcopy(self.request.GET) url_param['page'] = page_num return url_param.urlencode() # 确定页码的起始位置和结束位置 def page_point(self): # 如果总页码<11个 if self.all_pager <= self.pager_count: page_start = 1 page_end = self.all_pager + 1 else: # 当前页如果<=页面上做多显示11/2个页码 if self.current_page_num <= self.pager_count_half: page_start = 1 page_end = self.pager_count + 1 # 当前页大于5 else: # 页码翻到最后 if (self.current_page_num + self.pager_count_half) > self.all_pager: page_start = self.all_pager - self.pager_count + 1 page_end = self.all_pager + 1 else: page_start = self.current_page_num - self.pager_count_half page_end = self.current_page_num + self.pager_count_half + 1 return page_end, page_start # 返回HTML,返回data数据 def page_html(self): page_end, page_start = self.page_point() page_html_list = [] # 首页 first_page = '<li><a href="?%s">首页</a></li>' % (self.get_param(1),) page_html_list.append(first_page) if self.current_page_num <= 1: prev_page = '<li class="disabled"><a href="#">上一页</a></li>' else: prev_page = '<li><a href="?%s">上一页</a></li>' % (self.get_param(self.current_page_num - 1),) page_html_list.append(prev_page) for i in range(page_start, page_end): if i == self.current_page_num: temp = '<li class="active"><a href="?%s">%s</a></li>' % (self.get_param(i), i) else: temp = '<li><a href="?%s">%s</a></li>' % (self.get_param(i), i,) page_html_list.append(temp) if self.current_page_num >= self.all_pager: next_page = '<li class="disabled"><a href="#">下一页</a></li>' else: next_page = '<li><a href="?%s">下一页</a></li>' % (self.get_param(self.current_page_num + 1),) page_html_list.append(next_page) # 尾页 last_page = '<li><a href="?%s">尾页</a></li>' % (self.get_param(self.all_pager),) page_html_list.append(last_page) self.insert_obj_num() return ''.join(page_html_list), self.data_obj

 使用:

views.py

# 查看书籍
def show_book(request):
    current_page_num = request.GET.get('page', 1)
    all_book = Book.objects.all()
    pagination = Pagination(request, current_page_num, all_book, per_page_num=10)
    page_html, bookdata = pagination.page_html()

    return render(request, 'show_book.html', locals())

 

页面渲染:

show_book.html

{% extends 'base.html' %}

{% block css %}
    <link rel="stylesheet" href="/static/css/animate.min.css">
    <link rel="stylesheet" href="/static/css/common.css">
{% endblock %}


{% block content %}
    <div class="show_hub">
        <a class="flipInX dialog btn btn-primary add_book">添加书籍</a>
        {% csrf_token %}
        <div id="HBox" class="animated zoomOut" style="display: none;">
            <div class="form-horizontal" style="color: black">
                {% csrf_token %}
                <div class="form-group">
                    <label for="title" class="col-sm-2 control-label">书籍名称</label>
                    <div class="col-sm-5">
                        <input type="text" class="form-control" id="title" placeholder="书籍名称" name="title">
                    </div>
                </div>
                <div class="form-group">
                    <label for="author" class="col-sm-2 control-label">作者</label>
                    <div class="col-sm-5">
                        <select class="form-control" name="author" id="author" multiple>
                            {% for author in all_author %}
                                <option value="{{ author.pk }}">{{ author.name }}</option>
                            {% endfor %}
                        </select>
                    </div>
                </div>
                <div class="form-group">
                    <label for="book_type" class="col-sm-2 control-label">书籍类型</label>
                    <div class="col-sm-5">
                        <select class="form-control" name="book_type" id="book_type" multiple>
                            {% for book_type in all_book_type %}
                                <option value="{{ book_type.pk }}">{{ book_type.btype }}</option>
                            {% endfor %}
                        </select>
                    </div>
                </div>
                <div class="form-group">
                    <label for="grade" class="col-sm-2 control-label">评分</label>
                    <div class="col-sm-5">
                        <input type="text" class="form-control" id="grade" placeholder="评分" name="grade">
                    </div>
                </div>
                <div class="form-group">
                    <label for="pub_date" class="col-sm-2 control-label">出版日期</label>
                    <div class="col-sm-6">
                        <input type="date" class="form-control" id="pub_date" placeholder="出版日期" name="pub_date">
                    </div>
                </div>
                <div class="form-group">
                    <label for="publish" class="col-sm-2 control-label">出版社</label>
                    <div class="col-sm-5">
                        <select class="form-control" name="publish" id="publish">
                            {% for publish in all_publish %}
                                <option value="{{ publish.pk }}">{{ publish.name }}</option>
                            {% endfor %}
                        </select>
                    </div>
                </div>
                <div class="form-group">
                    <label for="price" class="col-sm-2 control-label">价格</label>
                    <div class="col-sm-5">
                        <input type="text" class="form-control" id="price" placeholder="价格" name="price">
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-1 col-sm-10">
                        <button type="submit" class="btn btn-primary add-book" id="add-book">添加</button>
                    </div>
                </div>
            </div>
        </div>
        <table class="row table table-hover table-bordered table-striped text-center">
            <thead>
            <tr class="bg-success">
                <th class="col-md-1 text-center">编号</th>
                <th class="col-md-1 text-center">书籍名称</th>
                <th class="col-md-2 text-center">作者</th>
                <th class="col-md-1 text-center">书籍类型</th>
                <th class="col-md-1 text-center">评分</th>
                <th class="col-md-1 text-center">出版日期</th>
                <th class="col-md-2 text-center">出版社</th>
                <th class="col-md-1 text-center">价格</th>
                <th class="col-md-2 text-center">操作</th>
            </tr>
            </thead>
            <tbody page_id="{{ current_page }}" per_page={{ per_page }}>
            {% for data in bookdata %}
                <tr>
            <!--记录编号-->
<td class="title-id">{{ data.page_num }}</td> <td class="target">{{ data.title }}</td> <td> {% for author in data.authors.all %} <span>{{ author.name }}</span> {% if not forloop.last %} , {% endif %} {% endfor %} </td> <td> {% for book_type in data.book_type.all %} <span>{{ book_type.btype }}</span> {% if not forloop.last %} , {% endif %} {% endfor %} </td> <td>{{ data.grade }}</td> <td>{{ data.pub_date|date:'Y-m-d' }}</td> <td>{{ data.publish.name }}</td> <td>{{ data.price }}</td> <td> <a href="{% url 'edit_book' data.pk %}" class="btn btn-primary btn-sm">编辑</a> <button del_url="{% url 'del_book' data.pk %}" class="btn btn-sm btn-danger del-book">删除 </button> </td> </tr> {% endfor %} </tbody> </table>

     <!--分页--> <nav aria-label="Page navigation" class="text-center"> <ul class="pagination"> {{ page_html|safe }} </ul> </nav> </div> {% endblock %} {% block js %} <script src="/static/js/book.js"></script> <script src="/static/js/bootstrap.js"></script> <script src="/static/js/jquery.hDialog.min.js"></script> <script> // 弹出层 $('.dialog').hDialog({width: 700, height: 600, modalHide: false, isOverlay: false}); // 获取作者,出版社,书籍类型信息 $('.add_book').click(function () { $('#HBox #title,#price,#grade,#pub_date').val(''); $('#HBox #author,#publish,#book_type').html(''); $.ajax({ url: '/book/add/', type: 'post', data: { 'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val(), 'type': 'ajax' }, success: function (response) { response = JSON.parse(response); $.each(response, function (i, j) { if ($('#author').attr('id') == i) { $.each(j, function (i, author) { $('#author').append(`<option value='${author.pk}'>${author.name}</option>`) }) } else if ($('#book_type').attr('id') == i) { $.each(j, function (i, book_type) { $('#book_type').append(`<option value='${book_type.pk}'>${book_type.btype}</option>`) }) } else if ($('#publish').attr('id') == i) { $.each(j, function (i, publish) { $('#publish').append(`<option value='${publish.pk}'>${publish.name}</option>`) }) } }) } }) }); // 发送书籍数据 $('#add-book').click(function () { let author = JSON.stringify($('#author').val()); let book_type = JSON.stringify($('#book_type').val()); $.ajax({ url: '/book/add/', type: 'post', data: { csrfmiddlewaretoken: $('[name=csrfmiddlewaretoken]').val(), title: $('#title').val(), author: author, book_type: book_type, grade: $('#grade').val(), pub_date: $('#pub_date').val(), publish: $('#publish').val(), price: $('#price').val(), }, success: function (response) { // response = JSON.parse(response) let book_data = [ 'new', $('#title').val(), $('#author').find("option:selected").text(), $('#book_type').find("option:selected").text(), $('#grade').val(), $('#pub_date').val(), $('#publish').find("option:selected").text(), $('#price').val() ]; let template = $('tr').last().clone(); template.children().slice(0, -1).html(''); template.children().each(function (i, j) { $(this).html(book_data[i]) }); template.children().first().css('color', 'red'); template.children().last().children().last().attr('del_url', `/book/del/${response.pk}/`); template.children().last().children().first().attr('href', `/book/edit/${response.pk}/`); $('tbody').append(template); alert('添加成功'); $('#HBox #title,#price,#grade,#pub_date').val(''); $('#HBox #author,#publish,#book_type').html(''); $('#HBox').css('display', 'None') } }) }); </script> {% endblock %}

 

Django 分页器

d_pages.py

def page_cut(per_page, book_obj, request):
    per_page = per_page
    # 生成分页数据
    paginator = Paginator(book_obj, per_page)
    # 获取客户端上传的页码
    page = request.GET.get('page', 1)
    try:
        current_page = int(page)
        # 根据客户端上传的页码,返回对应页码数据
        page_data = paginator.page(page)
    # 捕获页码不是数字的异常,以及强制int失败的异常
    except (PageNotAnInteger, ValueError):
        page_data = paginator.page(1)
        current_page = 1
    # 页码超出范围的异常
    except EmptyPage:
        page_data = paginator.page(paginator.num_pages)
        current_page = paginator.num_pages

    # 分页页码
    if paginator.num_pages > 11:
        if current_page - 5 < 1:
            p_range = range(1, 11)
        elif current_page + 5 > paginator.num_pages:
            p_range = range(current_page - 5, paginator.num_pages + 1)
        else:
            p_range = range(current_page - 5, current_page + 5)
    else:
        p_range = paginator.page_range
    # 生成每条记录的页码数据
    start_page = (current_page - 1) * per_page + 1
    end_page = (current_page - 1) * per_page + per_page + 1
    page_num = list(range(start_page, end_page))
    # 遍历当前页码数据,给每个对象加入页码属性
    for i, el in enumerate(page_data):
        el.pag_num = page_num[i]
    return {'page_data': page_data, 'paginator': paginator, 'current_page': current_page, 'p_range': p_range,
            'per_page': per_page}

 

使用:

views.py

def show_douban_book(request):
    # Django 分页器
    douban_book_list = DoubanBook.objects.all()
    result = page_cut(15, douban_book_list, request)
    return render(request, 'show_douban_book.html', result)

页面渲染

 show_doubanbook.html

{% extends 'base.html' %}

{% block content %}
    <div class="show_hub center-block">
        <table class="row table table-hover table-bordered table-striped text-center">
            <thead>
            <tr class="bg-success">
                <th class="col-md-1">编号</th>
                <th class="col-md-1">类型</th>
                <th class="col-md-3">书名</th>
                <th class="col-md-1">评分</th>
                <th class="col-md-3">出版信息</th>
                <th class="col-md-3">操作</th>
            </tr>
            </thead>
            <tbody page_id="{{ current_page }}" per_page={{ per_page }}>
            {% for data in page_data %}
                <tr>
                    <td class="title-id">{{ data.pag_num }}</td>
                    <td class="book_type">{{ data.book_type }}</td>
                    <td class="target">{{ data.title }}</td>
                    <td>{{ data.grade }}</td>
                    <td>{{ data.author }}</td>
                    <td>
                        <a href="#" class="btn btn-primary btn-sm">收藏到我的书库</a>
                        <button del_url="{% url 'del_douban_book' data.pk %}" class="btn btn-danger btn-sm del-book">
                            删除
                        </button>
                    </td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
        <nav aria-label="Page navigation" class="text-center">
            <ul class="pagination">
                {% if page_data.has_previous %}
                    <li>
                        <a href="?page={{ page_data.previous_page_number }}" aria-label="Previous">
                            <span aria-hidden="true">&laquo;</span>
                        </a>
                    </li>
                {% else %}
                    <li class="disabled">
                        <a href="#" aria-label="Previous">
                            <span aria-hidden="true">&laquo;</span>
                        </a>
                    </li>
                {% endif %}

                {% for page_num in p_range %}
                    {% if page_num == current_page %}
                        <li class="active"><a href="?page={{ page_num }}">{{ page_num }}</a></li>
                    {% else %}
                        <li><a href="?page={{ page_num }}">{{ page_num }}</a></li>
                    {% endif %}

                {% endfor %}

                {% if page_data.has_next %}
                    <li>
                        <a href="?page={{ page_data.next_page_number }}" aria-label="Next">
                            <span aria-hidden="true">&raquo;</span>
                        </a>
                    </li>
                {% else %}
                    <li class="disabled">
                        <a href="#" aria-label="Next">
                            <span aria-hidden="true">&raquo;</span>
                        </a>
                    </li>
                {% endif %}

            </ul>
        </nav>
    </div>
{% endblock %}


{% block js %}
    <script src="/static/js/book.js"></script>
{% endblock %}

自定义分页原版

"""
分页组件使用示例:

    obj = Pagination(request.GET.get('page',1),len(USER_LIST),request.path_info)
    page_user_list = USER_LIST[obj.start:obj.end]
    page_html = obj.page_html()

    return render(request,'index.html',{'users':page_user_list,'page_html':page_html})


"""

class Pagination(object):

    def __init__(self,current_page_num,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_num = int(current_page_num)
        except Exception as e:
            current_page_num = 1

        if current_page_num <1:
            current_page_num = 1

        self.current_page_num = current_page_num

        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)  # 5

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

    @property
    def end(self):
        return self.current_page_num * 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_num <= self.pager_count_half:
                pager_start = 1
                pager_end = self.pager_count + 1

            # 当前页大于5
            else:
                # 页码翻到最后
                if (self.current_page_num + self.pager_count_half) > self.all_pager:

                    pager_start = self.all_pager - self.pager_count + 1
                    pager_end = self.all_pager + 1

                else:
                    pager_start = self.current_page_num - self.pager_count_half
                    pager_end = self.current_page_num + self.pager_count_half + 1

        page_html_list = []

        first_page = '<li><a href="?page=%s">首页</a></li>' % (1,)
        page_html_list.append(first_page)

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

        page_html_list.append(prev_page)

        for i in range(pager_start, pager_end):
            if i == self.current_page_num:
                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_num >= 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_num + 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)

        return ''.join(page_html_list)
View Code

 

posted on 2018-11-07 11:45  Louiszj  阅读(119)  评论(0)    收藏  举报

导航