Introduced the PaginationProxy object to simplify use in templates.
[philo.git] / contrib / penfield / utils.py
1 from django.core.paginator import Paginator
2
3
4 class PaginationProxy(object):
5         def __init__(self, paginator=None, page=None, objects=None):
6                 self.paginator = paginator
7                 self.page = page
8                 self.objects = objects
9         
10         @property
11         def page_range(self):
12                 if not self.paginator:
13                         return None
14                 
15                 return self.paginator.page_range
16         
17         @property
18         def num_pages(self):
19                 if not self.paginator:
20                         return None
21                 
22                 return self.paginator.num_pages
23         
24         @property
25         def page_number(self):
26                 if not self.page:
27                         return None
28                 
29                 return self.page.number
30         
31         def __bool__(self):
32                 return bool(self.paginator)
33
34
35 def paginate(objects, per_page=None, page_number=1):
36         """
37         Given a list of objects, return a (page, obj_list) tuple.
38         """
39         try:
40                 per_page = int(per_page)
41         except (TypeError, ValueError):
42                 # Then either it wasn't set or it was set to an invalid value
43                 return PaginationProxy(objects=objects)
44         
45         # There also shouldn't be pagination if the list is too short. Try count()
46         # first - good chance it's a queryset, where count is more efficient.
47         try:
48                 if objects.count() <= per_page:
49                         return PaginationProxy(objects=objects)
50         except AttributeError:
51                 if len(objects) <= per_page:
52                         return PaginationProxy(objects=objects)
53         
54         paginator = Paginator(objects, per_page)
55         try:
56                 page_number = int(page_number)
57         except:
58                 page_number = 1
59         
60         try:
61                 page = paginator.page(page_number)
62         except EmptyPage:
63                 page = None
64         
65         return PaginationProxy(paginator, page, objects)