Code

Ticket #2367: date_based_paginate.diff

File date_based_paginate.diff, 8.8 KB (added by apgwoz@…, 8 years ago)
Line 
1Index: django/views/generic/date_based.py
2===================================================================
3--- django/views/generic/date_based.py  (revision 3358)
4+++ django/views/generic/date_based.py  (working copy)
5@@ -1,6 +1,7 @@
6 from django.template import loader, RequestContext
7 from django.core.exceptions import ObjectDoesNotExist
8 from django.core.xheaders import populate_xheaders
9+from django.core.paginator import ObjectPaginator, InvalidPage
10 from django.http import Http404, HttpResponse
11 import datetime, time
12 
13@@ -92,10 +93,10 @@
14             c[key] = value
15     return HttpResponse(t.render(c), mimetype=mimetype)
16 
17-def archive_month(request, year, month, queryset, date_field,
18-        month_format='%b', template_name=None, template_loader=loader,
19-        extra_context=None, allow_empty=False, context_processors=None,
20-        template_object_name='object', mimetype=None):
21+def archive_month(request, year, month, queryset, date_field, paginate_by=None,
22+        page=None, month_format='%b', template_name=None,
23+        template_loader=loader, extra_context=None, allow_empty=False,
24+        context_processors=None, template_object_name='object', mimetype=None):
25     """
26     Generic monthly archive view.
27 
28@@ -109,6 +110,24 @@
29             (date) the first day of the previous month
30         object_list:
31             list of objects published in the given month
32+        is_paginated
33+            are the results paginated?
34+        results_per_page
35+            number of objects per page (if paginated)
36+        has_next
37+            is there a next page?
38+        has_previous
39+            is there a prev page?
40+        page
41+            the current page
42+        next
43+            the next page
44+        previous
45+            the previous page
46+        pages
47+            number of pages, total
48+        hits
49+            number of objects, total
50     """
51     if extra_context is None: extra_context = {}
52     try:
53@@ -133,6 +152,20 @@
54     object_list = queryset.filter(**lookup_kwargs)
55     if not object_list and not allow_empty:
56         raise Http404
57+
58+    if paginate_by:
59+        paginator = ObjectPaginator(object_list, paginate_by)
60+        if not page:
61+            page = request.GET.get('page', 1)
62+        try:
63+            page = int(page)
64+            object_list = paginator.get_page(page - 1)
65+        except (InvalidPage, ValueError):
66+            if page == 1 and allow_empty:
67+                object_list = []
68+            else:
69+                raise Http404
70+
71     if not template_name:
72         template_name = "%s/%s_archive_month.html" % (model._meta.app_label, model._meta.object_name.lower())
73     t = template_loader.get_template(template_name)
74@@ -142,15 +175,30 @@
75         'next_month': (last_day < datetime.date.today()) and (last_day + datetime.timedelta(days=1)) or None,
76         'previous_month': first_day - datetime.timedelta(days=1),
77     }, context_processors)
78+
79     for key, value in extra_context.items():
80         if callable(value):
81             c[key] = value()
82         else:
83             c[key] = value
84+
85+    if paginate_by:
86+        c['is_paginated'] = paginator.pages > 1
87+        c['results_per_page'] = paginate_by
88+        c['has_next'] = paginator.has_next_page(page - 1)
89+        c['has_previous'] = paginator.has_previous_page(page - 1)
90+        c['page'] = page
91+        c['next'] = page + 1
92+        c['previous'] = page - 1
93+        c['pages'] = paginator.pages
94+        c['hits'] = paginator.hits
95+    else:
96+        c['is_paginated'] = False
97+
98     return HttpResponse(t.render(c), mimetype=mimetype)
99 
100-def archive_week(request, year, week, queryset, date_field,
101-        template_name=None, template_loader=loader,
102+def archive_week(request, year, week, queryset, date_field, paginate_by=None,
103+        page=None, template_name=None, template_loader=loader,
104         extra_context=None, allow_empty=True, context_processors=None,
105         template_object_name='object', mimetype=None):
106     """
107@@ -162,6 +210,24 @@
108             (date) this week
109         object_list:
110             list of objects published in the given week
111+        is_paginated
112+            are the results paginated?
113+        results_per_page
114+            number of objects per page (if paginated)
115+        has_next
116+            is there a next page?
117+        has_previous
118+            is there a prev page?
119+        page
120+            the current page
121+        next
122+            the next page
123+        previous
124+            the previous page
125+        pages
126+            number of pages, total
127+        hits
128+            number of objects, total
129     """
130     if extra_context is None: extra_context = {}
131     try:
132@@ -183,6 +249,18 @@
133     object_list = queryset.filter(**lookup_kwargs)
134     if not object_list and not allow_empty:
135         raise Http404
136+    if paginate_by:
137+        paginator = ObjectPaginator(object_list, paginate_by)
138+        if not page:
139+            page = request.GET.get('page', 1)
140+        try:
141+            page = int(page)
142+            object_list = paginator.get_page(page - 1)
143+        except (InvalidPage, ValueError):
144+            if page == 1 and allow_empty:
145+                object_list = []
146+            else:
147+                raise Http404
148     if not template_name:
149         template_name = "%s/%s_archive_week.html" % (model._meta.app_label, model._meta.object_name.lower())
150     t = template_loader.get_template(template_name)
151@@ -195,13 +273,25 @@
152             c[key] = value()
153         else:
154             c[key] = value
155+    if paginate_by:
156+        c['is_paginated'] = paginator.pages > 1
157+        c['results_per_page'] = paginate_by
158+        c['has_next'] = paginator.has_next_page(page - 1)
159+        c['has_previous'] = paginator.has_previous_page(page - 1)
160+        c['page'] = page
161+        c['next'] = page + 1
162+        c['previous'] = page - 1
163+        c['pages'] = paginator.pages
164+        c['hits'] = paginator.hits
165+    else:
166+        c['is_paginated'] = False
167     return HttpResponse(t.render(c), mimetype=mimetype)
168 
169 def archive_day(request, year, month, day, queryset, date_field,
170-        month_format='%b', day_format='%d', template_name=None,
171-        template_loader=loader, extra_context=None, allow_empty=False,
172-        context_processors=None, template_object_name='object',
173-        mimetype=None):
174+        paginate_by=None, page=None, month_format='%b', day_format='%d',
175+        template_name=None, template_loader=loader, extra_context=None,
176+        allow_empty=False, context_processors=None,
177+        template_object_name='object', mimetype=None):
178     """
179     Generic daily archive view.
180 
181@@ -215,6 +305,24 @@
182             (datetime) the previous day
183         next_day
184             (datetime) the next day, or None if the current day is today
185+        is_paginated
186+            are the results paginated?
187+        results_per_page
188+            number of objects per page (if paginated)
189+        has_next
190+            is there a next page?
191+        has_previous
192+            is there a prev page?
193+        page
194+            the current page
195+        next
196+            the next page
197+        previous
198+            the previous page
199+        pages
200+            number of pages, total
201+        hits
202+            number of objects, total
203     """
204     if extra_context is None: extra_context = {}
205     try:
206@@ -232,11 +340,24 @@
207     # Only bother to check current date if the date isn't in the past.
208     if date >= now.date():
209         lookup_kwargs['%s__lte' % date_field] = now
210-    object_list = queryset.filter(**lookup_kwargs)
211+    object_list = queryset.filter(**lookup_kwargs)   
212     if not allow_empty and not object_list:
213         raise Http404
214+    if paginate_by:
215+        paginator = ObjectPaginator(object_list, paginate_by)
216+        if not page:
217+            page = request.GET.get('page', 1)
218+        try:
219+            page = int(page)
220+            object_list = paginator.get_page(page - 1)
221+        except (InvalidPage, ValueError):
222+            if page == 1 and allow_empty:
223+                object_list = []
224+            else:
225+                raise Http404
226     if not template_name:
227         template_name = "%s/%s_archive_day.html" % (model._meta.app_label, model._meta.object_name.lower())
228+
229     t = template_loader.get_template(template_name)
230     c = RequestContext(request, {
231         '%s_list' % template_object_name: object_list,
232@@ -249,6 +370,18 @@
233             c[key] = value()
234         else:
235             c[key] = value
236+    if paginate_by:
237+        c['is_paginated'] = paginator.pages > 1
238+        c['results_per_page'] = paginate_by
239+        c['has_next'] = paginator.has_next_page(page - 1)
240+        c['has_previous'] = paginator.has_previous_page(page - 1)
241+        c['page'] = page
242+        c['next'] = page + 1
243+        c['previous'] = page - 1
244+        c['pages'] = paginator.pages
245+        c['hits'] = paginator.hits
246+    else:
247+        c['is_paginated'] = False
248     return HttpResponse(t.render(c), mimetype=mimetype)
249 
250 def archive_today(request, **kwargs):