Skip to content

Instantly share code, notes, and snippets.

@gileno
Created June 23, 2012 03:32
Show Gist options
  • Save gileno/2976689 to your computer and use it in GitHub Desktop.
Save gileno/2976689 to your computer and use it in GitHub Desktop.
Pagination Template Tag
{% if is_paginated %}
<div class="pagination pagination-right">
<ul>
{% if page_obj.has_previous %}
<li>
<a href="?page={{ page_obj.previous_page_number }}{{ getvars }}">&lsaquo;&lsaquo; anterior</a>
</li>
{% endif %}
{% for page in pages %}
{% if page %}
{% ifequal page page_obj.number %}
<li class="active">
<a href="?page={{ page }}{{ getvars }}">{{ page }}</a>
</li>
{% else %}
<li>
<a href="?page={{ page }}{{ getvars }}">{{ page }}</a>
</li>
{% endifequal %}
{% else %}
<li class="disabled">
<a href="javascript:void(0);">...</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>
<a href="?page={{ page_obj.next_page_number }}{{ getvars }}">próxima &rsaquo;&rsaquo;</a>
</li>
{% endif %}
</ul>
</div>
{% endif %}
# -*- coding: utf-8 -*-
from django.conf import settings
from django import template
register = template.Library()
DEFAULT_WINDOW = getattr(settings, 'PAGINATION_DEFAULT_WINDOW', 4)
@register.inclusion_tag(file_name='pagination.html', takes_context=True)
def pagination(context, window=DEFAULT_WINDOW):
"""
Renders the ``pagination/pagination.html`` template, resulting in a
Digg-like display of the available pages, given the current page. If there
are too many pages to be displayed before and after the current page, then
elipses will be used to indicate the undisplayed gap between page numbers.
Requires one argument, ``context``, which should be a dictionary-like data
structure and must contain the following keys:
``paginator``
A ``Paginator`` or ``QuerySetPaginator`` object.
``page_obj``
This should be the result of calling the page method on the
aforementioned ``Paginator`` or ``QuerySetPaginator`` object, given
the current page.
This same ``context`` dictionary-like data structure may also include:
``getvars``
A dictionary of all of the **GET** parameters in the current request.
This is useful to maintain certain types of state, even when requesting
a different page.
"""
try:
paginator = context['paginator']
page_obj = context['page_obj']
page_range = paginator.page_range
# First and last are simply the first *n* pages and the last *n* pages,
# where *n* is the current window size.
first = set([1])
last = set([paginator.num_pages])
# Now we look around our current page, making sure that we don't wrap
# around.
current_start = page_obj.number-1-window
if current_start < 0:
current_start = 0
current_end = page_obj.number-1+window
if current_end < 0:
current_end = 0
current = set(page_range[current_start:current_end])
pages = []
# If there's no overlap between the first set of pages and the current
# set of pages, then there's a possible need for elusion.
if len(first.intersection(current)) == 0:
first_list = list(first)
first_list.sort()
second_list = list(current)
second_list.sort()
pages.extend(first_list)
diff = second_list[0] - first_list[-1]
# If there is a gap of two, between the last page of the first
# set and the first page of the current set, then we're missing a
# page.
if diff == 2:
pages.append(second_list[0] - 1)
# If the difference is just one, then there's nothing to be done,
# as the pages need no elusion and are correct.
elif diff == 1:
pass
# Otherwise, there's a bigger gap which needs to be signaled for
# elusion, by pushing a None value to the page list.
else:
pages.append(None)
pages.extend(second_list)
else:
unioned = list(first.union(current))
unioned.sort()
pages.extend(unioned)
# If there's no overlap between the current set of pages and the last
# set of pages, then there's a possible need for elusion.
if len(current.intersection(last)) == 0:
second_list = list(last)
second_list.sort()
diff = second_list[0] - pages[-1]
# If there is a gap of two, between the last page of the current
# set and the first page of the last set, then we're missing a
# page.
if diff == 2:
pages.append(second_list[0] - 1)
# If the difference is just one, then there's nothing to be done,
# as the pages need no elusion and are correct.
elif diff == 1:
pass
# Otherwise, there's a bigger gap which needs to be signaled for
# elusion, by pushing a None value to the page list.
else:
pages.append(None)
pages.extend(second_list)
else:
differenced = list(last.difference(current))
differenced.sort()
pages.extend(differenced)
to_return = {
'MEDIA_URL': settings.MEDIA_URL,
'pages': pages,
'page_obj': page_obj,
'paginator': paginator,
'is_paginated': paginator.count > paginator.per_page,
}
if 'request' in context:
getvars = context['request'].GET.copy()
if 'page' in getvars:
del getvars['page']
if len(getvars.keys()) > 0:
to_return['getvars'] = "&%s" % getvars.urlencode()
else:
to_return['getvars'] = ''
return to_return
except KeyError, AttributeError:
return {}
# -*- coding: utf-8 -*-
from django.views.generic.list_detail import object_list
def minha_view(request):
template = 'meu_template.html'
context = {}
return object_list(request,
queryset=MeuModel.objects.all(),
template_name=template,
extra_context=context,
paginate_by=10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment