本文經過文章同步功能推送至博客園,顯示排版可能會有所錯誤,請見諒!
描述:Django框架內置了分頁功能,但其只能知足簡單需求,難以實現複雜功能。 html
實現代碼: python
#!/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 = '«','»' @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))
調用實例: web
在views.py中 django
page = Paginator(len(USER_LIST),15,p,7,'p',request.GET) bootstrap
page.setattr(attr={'class':'btn btn-default'}, current_attr={'class':'btn btn-default active'}) 框架
page.size = 'lg' spa
return render(request,'web/index.html', {'PAGE':page, 'USER_LIST':USER_LIST[page.start:page.end]}) code
在模板tempaltes中 orm
{{ PAGE.html }} 或者 {{ PAGE.bootstrap }} htm
bootstrap是直接使用bootstrap分頁樣式,無需過多設置,而html方法則能夠經過設置Paginator屬性等方式,靈活多變。