• Django框架下的增强分页组件


    本文通过文章同步功能推送至博客园,显示排版可能会有所错误,请见谅!

    描述:Django框架内置了分页功能,但其只能满足简单需求,难以实现复杂功能。

    实现代码:

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    __auth__ = 'Song Wei'
    
    from django.utils.safestring import mark_safe
    from math import ceil
    
    class Paginator:
        '''自定制分页功能,支持设置标签属性,支持展示页码,支持保留其他GET参数,支持页面跳转后元素定位。
        相关可用属性如下: 
            start   获取数据起始位置
            end     获取数据结束位置
            prvePage    上一页页码
            nextPage    下一页页码
            maxPage     总页码
            pvreCode    上一页显示文字
            nextCode    下一页显示文字
            attr        获取普通标签属性
            current_attr    获取当前页标签属性
            html        生成html标签 直接用于模板语言
            bootstrap   直接使用bootstrap分页样式 需要导入bootstrap
            bootstrap_size  仅使用boostrap时模板生效 可选设置lg(大),sm(小)
            position    支持分页跳转后定位至html指定id处
        相关可用方法如下:
            setattr(attr,current_attr=None,inheritance=True)    设置标签属性
            '''
    
        def __init__(self,totalCount,perPage,currentPage=1,pagerNumRange=0,argName='p',kwargs={}):
            ''' totalCount  数据总数量
                perPage     每页显示数量
                currentPage    当前页码
                pagerNumRange  上一页/下一页中间显示多少条数字页码 默认(0)不显示
                argName     传递页码的GET参数名 默认为p
                kwargs      补充其他GET参数 一般为空或直接传入request.GET
            '''
            self.maxPage = ceil(totalCount/perPage)
            try:
                self.currentPage = int(currentPage)
            except:
                self.currentPage = 1
            self.pagerNumRange = self._pager_num_range(pagerNumRange)
            self.argName = argName
            self.kwargs = ''
            for k,v in kwargs.items():
                if k != self.argName:
                    self.kwargs += '%s=%s&' % (k,v)
            self.end = self.currentPage * perPage
            self.start = self.end - perPage
            self.prvePage = self.currentPage - 1 if self.currentPage >1 else 1
            self.nextPage = self.currentPage + 1 if self.currentPage < self.maxPage else self.maxPage
            self.pattern = '<a {attr}href="?{kwargs}{argname}={href}">{content}</a> '
            self.attr,self._current_attr = '',''
            self.bootstrap_size = ''
            self.position = ''
            self.pvreCode,self.nextCode = '&laquo;','&raquo;'
    
        @property
        def current_attr(self):
            '''返回当前页标签属性'''
            if self._current_attr:
                return self._current_attr
            else:
                return self.attr
    
        def _pager_num_range(self,pager_num_range):
            '''分页显示页码数字列表'''
            if pager_num_range == 0:
                return []
            else:
                start = int(self.currentPage - (pager_num_range -1) / 2)
                end = int((self.currentPage + (pager_num_range - 1) / 2))
                if start < 1:
                    end += 1 - start
                    start = 1
                    if end > self.maxPage:
                        end = self.maxPage
                if end > self.maxPage:
                    start -= end - self.maxPage
                    end = self.maxPage
                    if start < 1:
                        start = 1
            return range(start,end+1)
    
        def setattr(self,attr,current_attr=None,inheritance=True):
            '''设置标签属性
                attr    普通标签属性
                current_attr    为当前页设置额外的属性
                inheritance     当前页属性是否继承普通标签属性'''
            self.attr = ''
            for k,v in attr.items():
                self.attr += '%s="%s" ' % (k,v)
            if current_attr:
                self._current_attr = ''
                if inheritance:
                    for k,v in attr.items():
                        if k in current_attr:
                            self._current_attr += '%s="%s" ' % (k, current_attr[k])
                        else:
                            self._current_attr += '%s="%s" ' % (k, v)
                    for k in current_attr.keys() - attr.keys():
                        self._current_attr += '%s="%s" ' % (k, current_attr[k])
                else:
                    for k,v in current_attr.items():
                        self._current_attr += '%s="%s" ' % (k, v)
    
        @property
        def html(self):
            '''生成html'''
            pagelist = ''
            position = '#' + self.position if self.position else ''
            if self.currentPage > 1:
                pagelist = self.pattern.format(attr=self.attr,href=str(self.prvePage) + position,
                                               kwargs=self.kwargs,argname=self.argName,content=self.pvreCode)
            for r in self.pagerNumRange:
                if r == self.currentPage:
                    pagelist += self.pattern.format(attr=self.current_attr, href=str(r) + position,
                                                    kwargs=self.kwargs, argname=self.argName,content=r)
                else:
                    pagelist += self.pattern.format(attr=self.attr,href=str(r) + position,
                                                    kwargs=self.kwargs, argname=self.argName,content=r)
            if self.currentPage < self.maxPage:
                pagelist += self.pattern.format(attr=self.attr,href=str(self.nextPage) + position,
                                                kwargs=self.kwargs, argname=self.argName,content=self.nextCode)
            return mark_safe(pagelist)
    
        @property
        def bootstrap(self):
            '直接使用bootstrap样式'
            html = '''
            <nav aria-label="Page navigation">
              <ul class="pagination">
                {pages}
              </ul>
            </nav>
            '''
            Previous = '''
                <li {disable}>
                  <a href="{prvePage}" aria-label="Previous">
                    <span aria-hidden="true">%s</span>
                  </a>
                </li>
            ''' % self.pvreCode
            Next = '''
                <li {disable}>
                  <a href="{nextPage}" aria-label="Next">
                    <span aria-hidden="true">%s</span>
                  </a>
                </li>
            ''' % self.nextCode
            pagelist = ''
            position = '#' + self.position if self.position else ''
            for r in self.pagerNumRange:
                if r == self.currentPage:
                    pagelist += '<li class="active"><a href="?%s%s=%s%s">%s<span class="sr-only">(current)</span></a></li>' % (self.kwargs,self.argname,r,position, r)
                else:
                    pagelist += '<li><a href="?%s%s=%s%s">%s</a></li>' % (self.kwargs,self.argName,r,position,r)
            if self.bootstrap_size in ('lg','sm'):
                html = html.replace('pagination','pagination pagination-%s' % self.bootstrap_size)
            if self.currentPage > 1:
                Previous = Previous.format(prvePage='?%s%s=%s' % (self.kwargs,self.argName,self.prvePage) + position,disable='')
            else:
                Previous = Previous.format(prvePage='#', disable='class="disabled"')
            if self.currentPage < self.maxPage:
                Next = Next.format(nextPage='?%s%s=%s' % (self.kwargs,self.argName,self.nextPage) + position,disable='')
            else:
                Next = Next.format(nextPage='#', disable='class="disabled"')
            return mark_safe(html.format(pages=Previous+pagelist+Next))

    调用实例:

    在views.py中

    page = Paginator(len(USER_LIST),15,p,7,'p',request.GET)

    page.setattr(attr={'class':'btn btn-default'}, current_attr={'class':'btn btn-default active'})

    page.size = 'lg'

    return render(request,'web/index.html', {'PAGE':page, 'USER_LIST':USER_LIST[page.start:page.end]})

    在模板tempaltes中

    {{ PAGE.html }} 或者 {{ PAGE.bootstrap }}

    bootstrap是直接使用bootstrap分页样式,无需过多设置,而html方法则可以通过设置Paginator属性等方式,灵活多变。

  • 相关阅读:
    react 全局监听报错,监听白屏
    【Python】(八)Python中的set集合(每个人都是唯一的个体)
    【Python】(六)Python数据类型-列表和元组,九浅一深,用得到
    mybatis-spring多数据源配置
    自己动手实现springboot运行时新增/更新外部接口
    自己动手实现springboot运行时执行java源码(运行时编译、加载、注册bean、调用)
    自己动手实现java断点/单步调试(一)
    自己动手实现java断点/单步调试(二)
    Swift 模式下面LLDB 输出对象
    Understanding Swift’s value type thread safety
  • 原文地址:https://www.cnblogs.com/lazyfish007/p/11487542.html
Copyright © 2020-2023  润新知