from django import template from django.db.models.query import QuerySet from django.core.paginator import Paginator, QuerySetPaginator register = template.Library() class PaginateNode(template.Node): def __init__(self, objlist_name, nr_pages, var_name="page", param_name="page"): self.objlist_name = objlist_name self.nr_pages = nr_pages self.var_name = var_name self.param_name = param_name def render(self, context): try: list_or_queryset = context[self.objlist_name] except KeyError: return '' if isinstance(list_or_queryset, QuerySet): paginator = QuerySetPaginator(list_or_queryset, self.nr_pages) else: paginator = Paginator(list_or_queryset, self.nr_pages) try: page = int(context['request'].REQUEST.get(self.param_name, 1)) except: page = 1 context[self.var_name] = paginator.page(page) context[self.var_name+"_set"] = paginator # backward compatibility injections into the context context[self.var_name+"_count"] = paginator.count context[self.var_name+"_num_pages"] = paginator.num_pages context[self.var_name+"_page_range"] = paginator.page_range return '' def paginate(parser, token): try: tag_name, arg = token.contents.split(None, 1) except ValueError: raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0] args = arg.split(None) var_name = "page" param_name = "page" try: objlist_name = args[0] nr_pages = args[1] except: raise template.TemplateSyntaxError, "%r tag invalid arguments" % token.contents.split()[0] if len(args)==2: pass elif len(args)==4 and args[2]=="as": var_name = args[3] elif len(args)==6 and args[4]=="using": var_name = args[3] param_name = args[5] else: raise template.TemplateSyntaxError, "%r tag invalid arguments" % token.contents.split()[0] try: nr_pages = int(nr_pages) except: raise template.TemplateSyntaxError, "%r tag invalid arguments" % token.contents.split()[0] return PaginateNode(objlist_name, nr_pages, var_name, param_name) paginate = register.tag(paginate)