Skip to content

Instantly share code, notes, and snippets.

@volgoweb
Last active November 25, 2019 06:00
Show Gist options
  • Save volgoweb/ab014c3b36f59ba58f656dfbbdf5d35e to your computer and use it in GitHub Desktop.
Save volgoweb/ab014c3b36f59ba58f656dfbbdf5d35e to your computer and use it in GitHub Desktop.
pagination frontend with Django
#
# File templatetags/custom_pagination.py
#
from django import template
register = template.Library()
@register.simple_tag
def add_param_into_url(url: str, key: str, value: str):
if key in url:
try:
idx = url.index('?%s=' % key)
except ValueError:
try:
idx = url.index('&%s=' % key)
except ValueError:
idx = None
if idx:
val_idx = url.index('=', idx) + 1
try:
end_val_idx = url.index('&', val_idx)
old_value = url[val_idx: end_val_idx]
except ValueError:
old_value = url[val_idx:]
url = url.replace('{}={}'.format(key, old_value), '{}={}'.format(key, value))
else:
if '?' in url:
if url.endswith('?'):
url += '{key}={value}'.format(**locals())
else:
url += '&{key}={value}'.format(**locals())
else:
url += '?{key}={value}'.format(**locals())
return url
@register.filter
def pagination_range(obj, current=1, limit=5):
left = (limit // 2) + 1
right = limit // 2
total = len(obj)
if limit % 2 == 0:
right -= 1
_range = []
if current < left:
_range = list(obj[:limit])
if current > total - right:
_range = list(obj[total-limit:])
idx_from = current - left
idx_to = current + right
if not _range:
_range = list(obj[idx_from:idx_to])
first_page = _range[0]
if first_page > 1:
_range.insert(0, 1)
if first_page - 1 > 1:
_range.insert(1, -1)
last_page = _range[len(_range) - 1]
num_pages = len(obj)
if last_page < num_pages:
if num_pages - last_page > 1:
_range.append(-1)
_range.append(num_pages)
return _range
{% load custom_pagination %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="{% add_param_into_url request.get_full_path 'page' page_obj.previous_page_number %}">
{% trans "Previous" %}
</a>
</li>
{% endif %}
{% for page in paginator.page_range|pagination_range:page_obj.number %}
{% if page == -1 %}
<li class="page-item"><a class="page-link" disabled>...</a></li>
{% else %}
<li class="page-item {% if page == page_obj.number %}active{% endif %}">
<a class="page-link" href="{% add_param_into_url request.get_full_path 'page' page %}">{{ page }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="{% add_param_into_url request.get_full_path 'page' page_obj.next_page_number %}">
{% trans "Next" %}
</a>
</li>
{% endif %}
</ul>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment