[Fixed]-Django pagination and "current page"


Hmm… I see from your comment that you don’t want to do the ol’ GET parameter, which is what django.core.paginator was written for using. To do what you want, I can think of no better way than to precompute the page that each question is on. As an example, your view will end up being something like:

def show_question(question_pk):
    questions = Question.objects.all()
    for index, question in enumerate(questions):
        question.page = ((index - 1) / ITEMS_PER_PAGE) + 1
    paginator = Paginator(questions, ITEMS_PER_PAGE)
    page = paginator.page(questions.get(pk=question_pk).page)
    return render_to_response('show_question.html', { 'page' : page })

To highlight the current page in the template, you’d do something like

{% for i in page.paginator.page_range %}
    {% ifequal i page.number %}
        <!-- Do something special for this page -->
    {% else %}
        <!-- All the other pages -->
    {% endifequal %}
{% endfor %}

As for the items, you’ll have two different object_lists to work with…


will be the objects in the current page and


will be all objects, regardless of page. Each of those items will have a “page” variable that will tell you which page they’re on.

That all said, what you’re doing sounds unconventional. You may want to rethink, but either way, good luck.



Django, at least from version 1.2, allows us to complete this task by using pure default pagination template tags.

{% for page in article_list.paginator.page_range %}
  {% if page == article_list.number %}
    {{ page }}
  {% else %}
    <a href="/page{{ page }}">{{ page }}</a>
  {% endif %}
{% endfor %}

Where article_list is instance of

paginator = Paginator(article_list, 20)
        article_list = paginator.page(int(page))
    except (EmptyPage, InvalidPage):
        article_list = paginator.page(paginator.num_pages)


django-pagination should do what you want and comes wrapped in a pretty package you can just plug-in and use. It essentially moves the code from your views to the templates and a middleware.

EDIT: I just saw your edit.
You can get the current objects on a page using {% autopaginate object_list %}, which replaces object_list with the current objects for any given page. You can iterate through it and if you want the first, you should be able to treat it like a list and do object_list[0].

If you want to keep this within your views, you could do something like this:

def show_question(question_pk):
    questions = Question.objects.all()
    paginator = Paginator(questions, 20)
    return render_to_response('show_question.html', { 'page' : paginator })

Within your template, you can access the current page you’re on by doing:

# Gives you the starting index for that page.
# For example, 5 objects, and you're on the second page. 
# start_index will be 3.

# You can access the current page number with:
# 1-based index

With that, you should be able to do everything you need.
There are a couple good examples here.

Leave a comment