Paginating the results of a Django form POST request

django forms pagination

This is quite a common situation, we have a search form which leads to a result page. The number of found results can be big enough to require pagination. If we use the classic pagination code, the posted parameters will be lost when changing page and our search gets broken.

There are several ways to solve the problem, as tux21b wrote in this stack overflow answer.

Here I will talk about the first method, using session.
In the same stack overflow page you can see an answer by rvnovaes, which surely works but in my opinion has some eliminable drawbacks. The first is that if there are many search fields the code we have to write is too long (yes I'm lazy). The second is that if we'd like to show the form also in the results page, the inputed values are lost, not displayed in the form.

So I'd rather store the entire request.POST dictionary in session, and rewrite the request.POST and request.method properties at the beginning of the view if the session is defined. The code explains itsef better than my words. In the example the search form allows to search for persons.

def index_person(request):

    persons = Person.objects.all()
    tot = persons.count()

    if not request.method == 'POST':
        if 'search-persons-post' in request.session:
            request.POST = request.session['search-persons-post']
            request.method = 'POST'

    if request.method == 'POST':
        form = PersonForm(request.POST)
        request.session['search-persons-post'] = request.POST
        if form.is_valid():
            id = form.cleaned_data['id']
            sex = form.cleaned_data['sex']
            birth_date = form.cleaned_data['birth_date']
            """ ... """

                persons = persons.filter(id = id)
                persons = persons.filter(sex = sex)
                persons = persons.filter(birth_date = birth_date)
            """ ... """

            persons = persons.distinct()

        form = PersonForm()

    table = PersonsTable(persons)
    RequestConfig(request, paginate={"per_page": 10}).configure(table)

    dict = {
        'table': table,
        'search_tot': persons.count(),
        'form': form,
        'tot': tot,

    return render_to_response('person/index_person.html', dict, context_instance=RequestContext(request))

The bold lines are the ones that do the trick. Clearly each research remains in session, even when leaving and revisiting the page, this is the drawback of using sessions (also it is not possible to perform multiple searches ).

That's it, hasta la proxima!

Subscribe to abidibo.net!

If you want to stay up to date with new contents published on this blog, then just enter your email address, and you will receive blog updates! You can set you preferences and decide to receive emails only when articles are posted regarding a precise topic.

I promise, you'll never receive spam or advertising of any kind from this subscription, just content updates.

Subscribe to this blog

Comments are welcome!

blog comments powered by Disqus

Your Smartwatch Loves Tasker!

Your Smartwatch Loves Tasker!

Now available for purchase!