2 django系列之django分页与templatetags

preface

当页面出现的条目多的时候,我们就需要使用分页功能了。Django作为一个知名的web框架,自然也提供了分页功能,下面说说它。

Python-shell 练练手

在python下入手

先创建一个操作对象
>>> hehe = ['ljf','richer','wang',1,2,3]
>>> hehe
['ljf', 'richer', 'wang', 1, 2, 3]
表示每页两份,表示把hehe这个列表每一页2份数据
>>> p = Paginator(hehe,2)       #表示每页两份,表示把hehe这个列表每一页2份数据
>>> p
<django.core.paginator.Paginator object at 0x0000000000B75630>
统计多少个值
>>> p.count           #统计多少个值
6
统计多少页
>>> p.num_pages         #统计多少页
3
查看页数
>>> p.page_range     #查看页数
range(1, 4)
取第一页的内容
>>> p1=p.page(1)       #取第一页的内容
>>> p1
>>> p1.object_list
['ljf', 'richer']
获取第二页
>>> p2=p.page(2)                 
>>> p2
<Page 2 of 3>
显示当前页内容
>>> p2.object_list
['wang', 1]
判断是否有一下页
>>> p2.has_next() #判断是否有一下页
True
判断是否有上一页
>>> p1.has_previous()            # 判断是否有上一页
False  
判断是否还有其他页
>>> p1.has_other_pages()          # 判断是否还有其他页
True

在html中使用分页功能

在html中,我们需要使用django 的templatetags功能来实现动态显示当前页的前后3页,避免页数过大导致页码太长。这个功能可以参考官网的例子(https://docs.djangoproject.com/en/1.10/howto/custom-template-tags/)。

我们首先查看项目目录,自己写的tag在app下面新建一个目录templatetags,必须是这个名字:

[root@salt devops]# tree BatchM
BatchM
├── Batch
│   ├── templatetags
│   │   ├── custom_tag.py   # 这个就是自己定义的tag.
│   │   ├── __init__.py
custom_tag.py的内容

from django import template

from django.utils.html import format_html
register = template.Library()   # 注册到tempate库里面


@register.filter   # filter只能对一个参数传入有效,调用到时候这样用  {{ xx.line  | ljf_power}} 
def ljf_lower(val):    #这个仅仅是测试练习写的代码,可以忽略。
    return val.lower()


@register.simple_tag()     # simple_tag能够对传入多个参数有效
def guess_page(current_page,loop_num):
    '''

    :param current_page:  当前页
    :param loop_num:     页数范围
    :return:
    '''

    offset = abs(current_page - loop_num)
    if offset < 3:   # 表示取当前页的前后三页
        if current_page == loop_num :
            page_element = '''       
            <li class="active"><a href="?page=%s">%s<span class="sr-only">(current)</span></a></li>
            '''%(loop_num,loop_num)                 # 拼html代码
        else:
            page_element = '''
            <li><a href="?page=%s">%s<span class="sr-only">(current)</span></a></li>
            '''%(loop_num,loop_num)
        return format_html(page_element)
    else:
        return ''                 # 必须写一个return 空字符串,这样就不会在前端页面显示None
我们再看看调用这个tags的html代码
提前引入bootstrap,jquery。
{% load custom_tag %}           # 需要引用刚才创建的tag
''''省略其他代码N行
            <nav>
              <ul class="pagination">
                {% if contacts.has_previous %}    <!-- 判断是否有首页  -->
                    <li class="disabled"><a href="#">&laquo;</a></li>
                {% endif %}

                  {% for page_num in contacts.paginator.page_range %}
                      {% guess_page contacts.number  page_num %}    <!--   guess_page 直接写刚才在tag里面定义的方法,  contacts.numer表示时当前页,page_num表示for循环到元素-->
                  {% endfor %}

              {% if contacts.has_next %}           <!-- 判断是否有下一页 -->
                 <li class="disabled"><a href="#">&raquo;</a></li>
              {% endif %}
              </ul>
            </nav>
再看views里面的代码:
def apply_update_search(request):
    '''
    :param request:
    :return:
    '''
    if request.method == 'GET':
        records = models.WorkOrderOfUpdate.objects.filter(username=request.user.get_username()).order_by('OrderId').reverse()  #数据库搜索
        page = request.GET.get('page')        # 与前端页面的a标签链接保持一致
        try:
            contacts = pageinator.page(page)
        except PageNotAnInteger:      # 如果输入到不是一个数字,发送第一页
            contacts = pageinator.page(1)
        except EmptyPage:   # 如果获取到超过来页数范围,那么就返回最后一页。
            contacts = pageinator.page(pageinator.num_pages)
        return render(request,'apply_update.html',{'btitle':'搜索操作记录','contacts':contacts})

url配置
url(r"apply_update.html/search",views.apply_update_search,name='post_order_id') 

以上功能完成后,就可以实现这样的功能:

posted @ 2016-12-29 00:16  温柔易淡  阅读(3146)  评论(0编辑  收藏  举报