4 from sets import Set as set
5 from django import template
6 from pagination.registration import get_registry, default_pagination
7 registry = get_registry()
8 from django.db.models.query import QuerySet
9 from django.core.paginator import Paginator, QuerySetPaginator, InvalidPage
10 #from django.template.loader import render_to_string
12 register = template.Library()
14 def do_autopaginate(parser, token):
15 split = token.split_contents()
17 return AutoPaginateNode()
19 return AutoPaginateNode(queryset_var=split[1])
21 raise template.TemplateSyntaxError('%r tag takes only one optional argument.' % split[0])
23 class AutoPaginateNode(template.Node):
24 def __init__(self, queryset_var=None):
26 self.queryset_var = template.Variable(queryset_var)
28 self.queryset_var = None
30 def render(self, context):
31 if self.queryset_var is not None:
33 key = self.queryset_var.var
34 value = self.queryset_var.resolve(context)
35 if issubclass(value.__class__, QuerySet):
37 paginator_class = QuerySetPaginator
41 model = value[0].__class__
44 paginator_class = Paginator
45 pagination = registry.get_for_model(model)
46 if pagination is None:
47 pagination = default_pagination
48 paginator = paginator_class(value, pagination)
50 page_obj = paginator.page(context['request'].page)
53 context[key] = page_obj.object_list
54 context['paginator'] = paginator
55 context['page_obj'] = page_obj
57 except template.VariableDoesNotExist:
60 for key, value in d.iteritems():
61 if issubclass(value.__class__, QuerySet):
63 pagination = registry.get_for_model(model)
64 if pagination is not None:
65 paginator = QuerySetPaginator(value, pagination)
67 page_obj = paginator.page(context['request'].page)
70 context[key] = page_obj.object_list
71 context['paginator'] = paginator
72 context['page_obj'] = page_obj
76 def paginate(context, window=4):
78 paginator = context['paginator']
79 page_obj = context['page_obj']
80 page_range = paginator.page_range
81 first = set(page_range[:window])
82 last = set(page_range[-window:])
83 current_start = page_obj.number-1-window
86 current_end = page_obj.number-1+window
89 current = set(page_range[current_start:current_end])
91 if len(first.intersection(current)) == 0:
92 first_list = sorted(list(first))
93 second_list = sorted(list(current))
94 pages.extend(first_list)
95 diff = second_list[0] - first_list[-1]
97 pages.append(second_list[0] - 1)
102 pages.extend(second_list)
104 pages.extend(sorted(list(first.union(current))))
105 if len(current.intersection(last)) == 0:
106 second_list = sorted(list(last))
107 diff = second_list[0] - pages[-1]
109 pages.append(second_list[0] - 1)
114 pages.extend(second_list)
116 pages.extend(sorted(list(last.difference(current))))
118 getvars = context['request'].GET.copy()
119 if 'page' in getvars:
123 'page_obj': page_obj,
124 'paginator': paginator,
125 'is_paginated': paginator.count > paginator.per_page,
126 'getvars': "&%s" % getvars.urlencode()
130 register.inclusion_tag('pagination/pagination.html', takes_context=True)(paginate)
131 register.tag('autopaginate', do_autopaginate)