Ticket #2367: 5992-pagination-for-datebased-generic-views.diff
File 5992-pagination-for-datebased-generic-views.diff, 16.4 KB (added by , 17 years ago) |
---|
-
django/core/paginator.py
86 86 87 87 hits = property(_get_hits) 88 88 pages = property(_get_pages) 89 90 def compute_pagination(paginator, page, paginate_by, allow_empty): 91 """ 92 Compute queryset considering pagination, and update the context. 93 """ 94 try: 95 page = int(page) 96 queryset = paginator.get_page(page - 1) 97 except (InvalidPage, ValueError): 98 if page == 1 and allow_empty: 99 queryset = paginator.query_set.empty() 100 else: 101 raise InvalidPage 102 103 c = {} 104 c['is_paginated'] = paginator.pages > 1 105 c['results_per_page'] = paginate_by 106 c['has_next'] = paginator.has_next_page(page - 1) 107 c['has_previous'] = paginator.has_previous_page(page - 1) 108 c['page'] = page 109 c['next'] = page + 1 110 c['previous'] = page - 1 111 c['last_on_page'] = paginator.last_on_page(page - 1), 112 c['first_on_page'] = paginator.first_on_page(page - 1), 113 c['pages'] = paginator.pages 114 c['hits'] = paginator.hits 115 116 return (queryset, c) -
django/views/generic/date_based.py
1 1 from django.template import loader, RequestContext 2 2 from django.core.exceptions import ObjectDoesNotExist 3 3 from django.core.xheaders import populate_xheaders 4 from django.core.paginator import compute_pagination, ObjectPaginator, InvalidPage 4 5 from django.db.models.fields import DateTimeField 5 6 from django.http import Http404, HttpResponse 6 7 import datetime, time … … 8 9 def archive_index(request, queryset, date_field, num_latest=15, 9 10 template_name=None, template_loader=loader, 10 11 extra_context=None, allow_empty=False, context_processors=None, 11 mimetype=None, allow_future=False ):12 mimetype=None, allow_future=False, paginate_by=None, page=None): 12 13 """ 13 14 Generic top-level archive of date-based objects. 14 15 … … 18 19 List of years 19 20 latest 20 21 Latest N (defaults to 15) objects by date 22 is_paginated 23 are the results paginated? 24 results_per_page 25 number of objects per page (if paginated) 26 has_next 27 is there a next page? 28 has_previous 29 is there a prev page? 30 page 31 the current page 32 next 33 the next page 34 previous 35 the previous page 36 pages 37 number of pages, total 38 hits 39 number of objects, total 40 last_on_page 41 the result number of the last of object in the 42 object_list (1-indexed) 43 first_on_page 44 the result number of the first object in the 45 object_list (1-indexed) 21 46 """ 22 47 if extra_context is None: extra_context = {} 23 48 model = queryset.model … … 30 55 if date_list and num_latest: 31 56 latest = queryset.order_by('-'+date_field)[:num_latest] 32 57 else: 33 latest = None58 latest = [] 34 59 60 # Pagination. 61 pagination_context = {'is_paginated': False} 62 if paginate_by: 63 paginator = ObjectPaginator(latest, paginate_by) 64 page = page or request.GET.get('page', 1) 65 try: 66 latest, pagination_context = compute_pagination(paginator, page, paginate_by, allow_empty) 67 except InvalidPage: 68 raise Http404 69 35 70 if not template_name: 36 71 template_name = "%s/%s_archive.html" % (model._meta.app_label, model._meta.object_name.lower()) 37 72 t = template_loader.get_template(template_name) … … 44 79 c[key] = value() 45 80 else: 46 81 c[key] = value 82 83 c.update(pagination_context) 84 47 85 return HttpResponse(t.render(c), mimetype=mimetype) 48 86 49 87 def archive_year(request, year, queryset, date_field, template_name=None, 50 88 template_loader=loader, extra_context=None, allow_empty=False, 51 89 context_processors=None, template_object_name='object', mimetype=None, 52 make_object_list=False, allow_future=False ):90 make_object_list=False, allow_future=False, paginate_by=None, page=None): 53 91 """ 54 92 Generic yearly archive view. 55 93 … … 61 99 This year 62 100 object_list 63 101 List of objects published in the given month 102 64 103 (Only available if make_object_list argument is True) 104 105 is_paginated 106 are the results paginated? 107 results_per_page 108 number of objects per page (if paginated) 109 has_next 110 is there a next page? 111 has_previous 112 is there a prev page? 113 page 114 the current page 115 next 116 the next page 117 previous 118 the previous page 119 pages 120 number of pages, total 121 hits 122 number of objects, total 123 last_on_page 124 the result number of the last of object in the 125 object_list (1-indexed) 126 first_on_page 127 the result number of the first object in the 128 object_list (1-indexed) 65 129 """ 66 130 if extra_context is None: extra_context = {} 67 131 model = queryset.model … … 79 143 object_list = queryset.filter(**lookup_kwargs).order_by(date_field) 80 144 else: 81 145 object_list = [] 146 147 # Pagination. 148 pagination_context = {'is_paginated': False} 149 if paginate_by: 150 paginator = ObjectPaginator(object_list, paginate_by) 151 page = page or request.GET.get('page', 1) 152 try: 153 object_list, pagination_context = compute_pagination(paginator, page, paginate_by, allow_empty) 154 except InvalidPage: 155 raise Http404 156 82 157 if not template_name: 83 158 template_name = "%s/%s_archive_year.html" % (model._meta.app_label, model._meta.object_name.lower()) 84 159 t = template_loader.get_template(template_name) … … 92 167 c[key] = value() 93 168 else: 94 169 c[key] = value 170 171 c.update(pagination_context) 172 95 173 return HttpResponse(t.render(c), mimetype=mimetype) 96 174 97 175 def archive_month(request, year, month, queryset, date_field, 98 176 month_format='%b', template_name=None, template_loader=loader, 99 177 extra_context=None, allow_empty=False, context_processors=None, 100 template_object_name='object', mimetype=None, allow_future=False): 178 template_object_name='object', mimetype=None, allow_future=False, 179 paginate_by=None, page=None): 101 180 """ 102 181 Generic monthly archive view. 103 182 … … 111 190 (date) the first day of the previous month 112 191 object_list: 113 192 list of objects published in the given month 193 is_paginated 194 are the results paginated? 195 results_per_page 196 number of objects per page (if paginated) 197 has_next 198 is there a next page? 199 has_previous 200 is there a prev page? 201 page 202 the current page 203 next 204 the next page 205 previous 206 the previous page 207 pages 208 number of pages, total 209 hits 210 number of objects, total 211 last_on_page 212 the result number of the last of object in the 213 object_list (1-indexed) 214 first_on_page 215 the result number of the first object in the 216 object_list (1-indexed) 114 217 """ 115 218 if extra_context is None: extra_context = {} 116 219 try: … … 144 247 else: 145 248 next_month = None 146 249 250 # Pagination. 251 pagination_context = {'is_paginated': False} 252 if paginate_by: 253 paginator = ObjectPaginator(object_list, paginate_by) 254 page = page or request.GET.get('page', 1) 255 try: 256 object_list, pagination_context = compute_pagination(paginator, page, paginate_by, allow_empty) 257 except InvalidPage: 258 raise Http404 259 147 260 if not template_name: 148 261 template_name = "%s/%s_archive_month.html" % (model._meta.app_label, model._meta.object_name.lower()) 149 262 t = template_loader.get_template(template_name) … … 158 271 c[key] = value() 159 272 else: 160 273 c[key] = value 274 275 c.update(pagination_context) 276 161 277 return HttpResponse(t.render(c), mimetype=mimetype) 162 278 163 279 def archive_week(request, year, week, queryset, date_field, 164 280 template_name=None, template_loader=loader, 165 281 extra_context=None, allow_empty=True, context_processors=None, 166 template_object_name='object', mimetype=None, allow_future=False): 282 template_object_name='object', mimetype=None, allow_future=False, 283 paginate_by=None, page=None): 167 284 """ 168 285 Generic weekly archive view. 169 286 … … 173 290 (date) this week 174 291 object_list: 175 292 list of objects published in the given week 293 is_paginated 294 are the results paginated? 295 results_per_page 296 number of objects per page (if paginated) 297 has_next 298 is there a next page? 299 has_previous 300 is there a prev page? 301 page 302 the current page 303 next 304 the next page 305 previous 306 the previous page 307 pages 308 number of pages, total 309 hits 310 number of objects, total 311 last_on_page 312 the result number of the last of object in the 313 object_list (1-indexed) 314 first_on_page 315 the result number of the first object in the 316 object_list (1-indexed) 176 317 """ 177 318 if extra_context is None: extra_context = {} 178 319 try: … … 194 335 object_list = queryset.filter(**lookup_kwargs) 195 336 if not object_list and not allow_empty: 196 337 raise Http404 338 339 # Pagination. 340 pagination_context = {'is_paginated': False} 341 if paginate_by: 342 paginator = ObjectPaginator(object_list, paginate_by) 343 page = page or request.GET.get('page', 1) 344 try: 345 object_list, pagination_context = compute_pagination(paginator, page, paginate_by, allow_empty) 346 except InvalidPage: 347 raise Http404 348 197 349 if not template_name: 198 350 template_name = "%s/%s_archive_week.html" % (model._meta.app_label, model._meta.object_name.lower()) 199 351 t = template_loader.get_template(template_name) … … 206 358 c[key] = value() 207 359 else: 208 360 c[key] = value 361 362 c.update(pagination_context) 363 209 364 return HttpResponse(t.render(c), mimetype=mimetype) 210 365 211 366 def archive_day(request, year, month, day, queryset, date_field, 212 367 month_format='%b', day_format='%d', template_name=None, 213 368 template_loader=loader, extra_context=None, allow_empty=False, 214 369 context_processors=None, template_object_name='object', 215 mimetype=None, allow_future=False ):370 mimetype=None, allow_future=False, paginate_by=None, page=None): 216 371 """ 217 372 Generic daily archive view. 218 373 … … 226 381 (datetime) the previous day 227 382 next_day 228 383 (datetime) the next day, or None if the current day is today 384 is_paginated 385 are the results paginated? 386 results_per_page 387 number of objects per page (if paginated) 388 has_next 389 is there a next page? 390 has_previous 391 is there a prev page? 392 page 393 the current page 394 next 395 the next page 396 previous 397 the previous page 398 pages 399 number of pages, total 400 hits 401 number of objects, total 402 last_on_page 403 the result number of the last of object in the 404 object_list (1-indexed) 405 first_on_page 406 the result number of the first object in the 407 object_list (1-indexed) 229 408 """ 230 409 if extra_context is None: extra_context = {} 231 410 try: … … 256 435 else: 257 436 next_day = None 258 437 438 # Pagination. 439 pagination_context = {'is_paginated': False} 440 if paginate_by: 441 paginator = ObjectPaginator(object_list, paginate_by) 442 page = page or request.GET.get('page', 1) 443 try: 444 object_list, pagination_context = compute_pagination(paginator, page, paginate_by, allow_empty) 445 except InvalidPage: 446 raise Http404 447 259 448 if not template_name: 260 449 template_name = "%s/%s_archive_day.html" % (model._meta.app_label, model._meta.object_name.lower()) 261 450 t = template_loader.get_template(template_name) … … 270 459 c[key] = value() 271 460 else: 272 461 c[key] = value 462 463 c.update(pagination_context) 464 273 465 return HttpResponse(t.render(c), mimetype=mimetype) 274 466 275 467 def archive_today(request, **kwargs): … … 288 480 month_format='%b', day_format='%d', object_id=None, slug=None, 289 481 slug_field='slug', template_name=None, template_name_field=None, 290 482 template_loader=loader, extra_context=None, context_processors=None, 291 template_object_name='object', mimetype=None, allow_future=False ):483 template_object_name='object', mimetype=None, allow_future=False, page=None): 292 484 """ 293 485 Generic detail view from year/month/day/slug or year/month/day/id structure. 294 486 … … 333 525 t = template_loader.get_template(template_name) 334 526 c = RequestContext(request, { 335 527 template_object_name: obj, 528 page: page 336 529 }, context_processors) 337 530 for key, value in extra_context.items(): 338 531 if callable(value): -
django/views/generic/list_detail.py
1 1 from django.template import loader, RequestContext 2 2 from django.http import Http404, HttpResponse 3 3 from django.core.xheaders import populate_xheaders 4 from django.core.paginator import ObjectPaginator, InvalidPage4 from django.core.paginator import compute_pagination, ObjectPaginator, InvalidPage 5 5 from django.core.exceptions import ObjectDoesNotExist 6 6 7 7 def object_list(request, queryset, paginate_by=None, page=None, … … 42 42 """ 43 43 if extra_context is None: extra_context = {} 44 44 queryset = queryset._clone() 45 46 if not allow_empty and queryset.count() == 0: 47 raise Http404 48 49 # Pagination. 50 pagination_context = {'is_paginated': False} 45 51 if paginate_by: 46 52 paginator = ObjectPaginator(queryset, paginate_by) 47 if not page: 48 page = request.GET.get('page', 1) 53 page = page or request.GET.get('page', 1) 49 54 try: 50 page = int(page) 51 object_list = paginator.get_page(page - 1) 52 except (InvalidPage, ValueError): 53 if page == 1 and allow_empty: 54 object_list = [] 55 else: 56 raise Http404 57 c = RequestContext(request, { 58 '%s_list' % template_object_name: object_list, 59 'is_paginated': paginator.pages > 1, 60 'results_per_page': paginate_by, 61 'has_next': paginator.has_next_page(page - 1), 62 'has_previous': paginator.has_previous_page(page - 1), 63 'page': page, 64 'next': page + 1, 65 'previous': page - 1, 66 'last_on_page': paginator.last_on_page(page - 1), 67 'first_on_page': paginator.first_on_page(page - 1), 68 'pages': paginator.pages, 69 'hits' : paginator.hits, 70 }, context_processors) 71 else: 72 c = RequestContext(request, { 73 '%s_list' % template_object_name: queryset, 74 'is_paginated': False 75 }, context_processors) 76 if not allow_empty and len(queryset) == 0: 55 queryset, pagination_context = compute_pagination(paginator, page, paginate_by, allow_empty) 56 except InvalidPage: 77 57 raise Http404 58 c = RequestContext(request, { 59 '%s_list' % template_object_name: queryset, 60 }, context_processors) 78 61 for key, value in extra_context.items(): 79 62 if callable(value): 80 63 c[key] = value() 81 64 else: 82 65 c[key] = value 66 67 c.update(pagination_context) 68 83 69 if not template_name: 84 70 model = queryset.model 85 71 template_name = "%s/%s_list.html" % (model._meta.app_label, model._meta.object_name.lower())