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 }}
{% endfor %}
{% if previous_exists %}previous{% endif %} {% if next_exists %} next {% 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