Skip to content

Instantly share code, notes, and snippets.

@vaad2
Created July 20, 2016 08:51
Show Gist options
  • Save vaad2/7623735ecfbd76bfefc9e1e7624e5efe to your computer and use it in GitHub Desktop.
Save vaad2/7623735ecfbd76bfefc9e1e7624e5efe to your computer and use it in GitHub Desktop.
paginator
class VTPaginator(dict):
def __init__(self, num_rows, **kwargs):
defaults = {
'offset': 0,
'limit': 10,
'view_num': 11,
'splitter': '...',
'view_one_page': False,
'min_limit': 10,
'max_limit': 50,
'params': None,
'offset_name': 'offset',
'is_range': False
}
defaults.update(kwargs)
self.update(defaults)
self['num_rows'] = num_rows
if self['limit'] < self['min_limit']:
self['limit'] = self['min_limit']
if self['limit'] > self['max_limit']:
self['limit'] = self['max_limit']
if self['offset'] > self['num_rows']:
self['offset'] = self['num_rows'] - self['limit']
if self['offset'] < 0:
self['offset'] = 0
self['num_pages'] = int(math.ceil(float(self['num_rows'])
/ self['limit']))
self['curr_page'] = int(math.ceil(self['offset'] / self['limit']))
self['next_page'] = self['curr_page'] + 1
if self['next_page'] >= self['num_pages']:
self['next_page'] = self['num_pages'] - 1
self['prev_page'] = self['curr_page'] - 1
if self['prev_page'] < 0:
self['prev_page'] = 0
self['offset_next_page'] = self['limit'] * self['next_page']
self['offset_prev_page'] = self['limit'] * self['prev_page']
self['offset_last_page'] = self['limit'] * (self['num_pages'] - 1)
self['curr_page'] += 1
self['next_page'] += 1
self['prev_page'] += 1
if self['params']:
items = {}
for key, val in self['params'].iteritems():
if isinstance(val, str) or isinstance(val, unicode):
items[key] = val.encode('utf-8')
else:
items[key] = val
self['params'] = items
self['is_last'] = (self['offset'] + self['limit']) >= self['num_rows']
self['page_xrange'] = self._get_page_range()
self['page_range'] = list(self._get_page_range()) if self[
'is_range'] else None
def _page(self, i):
offset = (i - 1) * self['limit']
params = dict(self['params'])
params[self['offset_name']] = offset
return {
'n': i,
'o': offset,
'url_params': urllib.urlencode(params),
'is_current': self['curr_page'] == i
}
@property
def first_page(self):
return self._page(1)
@property
def last_page(self):
return self._page(self['num_pages'])
@property
def next_page(self):
return self._page(self['next_page'])
@property
def prev_page(self):
return self._page(self['prev_page'])
def _get_page_range(self):
num_pages = self['num_pages']
splitter = {'is_splitter': True,
'splitter': self['splitter']}
view_num = self['view_num']
curr_page = self['curr_page']
if num_pages <= view_num:
for i in xrange(1, num_pages + 1):
yield self._page(i)
else:
df = view_num / 2
if curr_page <= df:
for i in xrange(1, view_num):
yield self._page(i)
yield splitter
elif curr_page >= num_pages - df:
yield self._page(1)
yield splitter
for i in xrange(num_pages - view_num + 2, num_pages):
yield self._page(i)
else:
yield self._page(1)
if curr_page != df + 1:
yield splitter
for i in xrange(curr_page - df + 1, curr_page + df):
yield self._page(i)
if curr_page != num_pages - df:
yield splitter
yield self._page(num_pages)
'''
{% if paginator and paginator.num_pages > 1 %}
<div class="m_pagination">
<ul>
<li><a href="?{{ paginator.first_page.url_params }}">В начало</a></li>
<li><a href="?{{ paginator.prev_page.url_params }}" class="prev"></a></li>
{% for page in paginator.page_xrange %}
{% if page.is_splitter %}
<li><span>{{ page.splitter }}</span></li>
{% else %}
{% if page.is_current %}
<li><a class="current" href="javascript:void(0);">{{ page.n }}</a></li>
{% else %}
<li><a href="?{{ page.url_params }}">{{ page.n }}</a></li>
{% endif %}
{% endif %}
{% endfor %}
<li><a href="?{{ paginator.next_page.url_params }}" class="next"></a></li>
<li><a href="?{{ paginator.last_page.url_params }}">В конец</a></li>
</ul>
</div>
{% endif %}
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment