Paginator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from django.core.paginator import ObjectPaginator, InvalidPage
def paginate_by(name='records_list', per_page=10):
"""
This decorator used along with render_to decorator, placed on top of django function
in views and below render_to. The view shoud contain 'paginate_qs' key with queryset of all
model records needed to be paginated and 'page_num' key with number of current page.
parameters:
[optional]
- name: name for variable that will contain records of current page.
if doesn't provided, using 'records_list'.
- per_page: number of records per page, 10 by default if not provided.
It's add couple variables to view returning dictionary:
- 'next_page' : next teoretical page number.
- 'previous_page' : previous teoretical page number.
- 'next_exists' : return True if next page exists.
- 'previous_exists' : return True if previous page exists.
- name : variable name recived by decorator, used for returning records of current page.
Examples:
===View===
@render_to('test.html')
@paginate_by('news', 5)
def test(request, page="1"):
articles = Article.objects.order_by('id')
page_num = int(page)
return {'paginate_qs': articles, 'page_num': page_num}
===Template==
{% for i in news %}
{{ i.name }} <br />
{% endfor %}
<br />
{% if previous_exists %}<a href="/{{ previous_page }}/">previous</a>{% endif %} {% if next_exists %} <a href="/{{ next_page }}/">next</a> {% endif %}
"""
def decorator(func):
def wrapper(request, *args, **kw):
output = func(request, *args, **kw)
paginate_qs = output.pop('paginate_qs')
paginator = ObjectPaginator(paginate_qs, per_page)
page_num = output.get('page_num') - 1
kw[name] = paginator.get_page(page_num)
kw['next_page'] = page_num + 2
kw['previous_page'] = page_num
kw['next_exists'] = paginator.has_next_page(page_num)
kw['previous_exists'] = paginator.has_previous_page(page_num)
return kw
return wrapper
return decorator