X-Git-Url: https://git.mdrn.pl/django-pagination.git/blobdiff_plain/6351d0071e6194c9fee3ec0df447acc84f6e4f7d..786f413a03df1e4d0485213d8c1d796d15ac114d:/pagination/templatetags/pagination_tags.py diff --git a/pagination/templatetags/pagination_tags.py b/pagination/templatetags/pagination_tags.py index 3442fcd..c115720 100644 --- a/pagination/templatetags/pagination_tags.py +++ b/pagination/templatetags/pagination_tags.py @@ -2,7 +2,10 @@ try: set except NameError: from sets import Set as set + from django import template +from django.template import TOKEN_BLOCK +from django.http import Http404 from django.core.paginator import Paginator, InvalidPage from django.conf import settings @@ -11,11 +14,19 @@ register = template.Library() DEFAULT_PAGINATION = getattr(settings, 'PAGINATION_DEFAULT_PAGINATION', 20) DEFAULT_WINDOW = getattr(settings, 'PAGINATION_DEFAULT_WINDOW', 4) DEFAULT_ORPHANS = getattr(settings, 'PAGINATION_DEFAULT_ORPHANS', 0) +INVALID_PAGE_RAISES_404 = getattr(settings, + 'PAGINATION_INVALID_PAGE_RAISES_404', False) def do_autopaginate(parser, token): """ Splits the arguments to the autopaginate tag and formats them correctly. """ + + # Check whether there are any other autopaginations are later in this template + expr = lambda obj: (obj.token_type == TOKEN_BLOCK and \ + len(obj.split_contents()) > 0 and obj.split_contents()[0] == "autopaginate") + multiple_paginations = len(filter(expr, parser.tokens)) > 0 + split = token.split_contents() as_index = None context_var = None @@ -27,24 +38,25 @@ def do_autopaginate(parser, token): try: context_var = split[as_index + 1] except IndexError: - raise template.TemplateSyntaxError("Context variable assignment " +\ - "must take the form of {%% %r object.example_set.all ... as " +\ + raise template.TemplateSyntaxError("Context variable assignment " + + "must take the form of {%% %r object.example_set.all ... as " + "context_var_name %%}" % split[0]) del split[as_index:as_index + 2] if len(split) == 2: - return AutoPaginateNode(split[1]) + return AutoPaginateNode(split[1], multiple_paginations=multiple_paginations) elif len(split) == 3: return AutoPaginateNode(split[1], paginate_by=split[2], - context_var=context_var) + context_var=context_var, multiple_paginations=multiple_paginations) elif len(split) == 4: try: orphans = int(split[3]) except ValueError: - raise template.TemplateSyntaxError(u'Got %s, but expected integer.' % split[3]) + raise template.TemplateSyntaxError(u'Got %s, but expected integer.' + % split[3]) return AutoPaginateNode(split[1], paginate_by=split[2], orphans=orphans, - context_var=context_var) + context_var=context_var, multiple_paginations=multiple_paginations) else: - raise template.TemplateSyntaxError('%r tag takes one required ' + \ + raise template.TemplateSyntaxError('%r tag takes one required ' + 'argument and one optional argument' % split[0]) class AutoPaginateNode(template.Node): @@ -64,7 +76,7 @@ class AutoPaginateNode(template.Node): tag. If you choose not to use *{% paginate %}*, make sure to display the list of available pages, or else the application may seem to be buggy. """ - def __init__(self, queryset_var, paginate_by=DEFAULT_PAGINATION, + def __init__(self, queryset_var, multiple_paginations, paginate_by=DEFAULT_PAGINATION, orphans=DEFAULT_ORPHANS, context_var=None): self.queryset_var = template.Variable(queryset_var) if isinstance(paginate_by, int): @@ -73,8 +85,14 @@ class AutoPaginateNode(template.Node): self.paginate_by = template.Variable(paginate_by) self.orphans = orphans self.context_var = context_var + self.multiple_paginations = multiple_paginations def render(self, context): + if self.multiple_paginations or context.has_key('paginator'): + page_suffix = '_%s' % self.queryset_var + else: + page_suffix = '' + key = self.queryset_var.var value = self.queryset_var.resolve(context) if isinstance(self.paginate_by, int): @@ -83,8 +101,11 @@ class AutoPaginateNode(template.Node): paginate_by = self.paginate_by.resolve(context) paginator = Paginator(value, paginate_by, self.orphans) try: - page_obj = paginator.page(context['request'].page) + page_obj = paginator.page(context['request'].page(page_suffix)) except InvalidPage: + if INVALID_PAGE_RAISES_404: + raise Http404('Invalid page requested. If DEBUG were set to ' + + 'False, an HTTP 404 page would have been shown instead.') context[key] = [] context['invalid_page'] = True return u'' @@ -94,6 +115,7 @@ class AutoPaginateNode(template.Node): context[key] = page_obj.object_list context['paginator'] = paginator context['page_obj'] = page_obj + context['page_suffix'] = page_suffix return u'' def paginate(context, window=DEFAULT_WINDOW): @@ -124,6 +146,7 @@ def paginate(context, window=DEFAULT_WINDOW): try: paginator = context['paginator'] page_obj = context['page_obj'] + page_suffix = context.get('page_suffix', '') 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. @@ -195,11 +218,12 @@ def paginate(context, window=DEFAULT_WINDOW): 'page_obj': page_obj, 'paginator': paginator, 'is_paginated': paginator.count > paginator.per_page, + 'page_suffix': page_suffix, } if 'request' in context: getvars = context['request'].GET.copy() - if 'page' in getvars: - del getvars['page'] + if 'page%s' % page_suffix in getvars: + del getvars['page%s' % page_suffix] if len(getvars.keys()) > 0: to_return['getvars'] = "&%s" % getvars.urlencode() else: @@ -207,5 +231,7 @@ def paginate(context, window=DEFAULT_WINDOW): return to_return except KeyError, AttributeError: return {} -register.inclusion_tag('pagination/pagination.html', takes_context=True)(paginate) + +register.inclusion_tag('pagination/pagination.html', takes_context=True)( + paginate) register.tag('autopaginate', do_autopaginate)