Learn Django

List Accounts - Add Pagination

The basic account list page is now working. However it's not optimally setup. What happens if the user has 1000 accounts? If they had that many accounts and accessed the list, their request would take a long time to render as it needs to query 1000 accounts from the database, and then iterate over each one to display it on the page.

This could add a several second delay to the user experience. If the user were to need all of this information at once then this delay might be acceptable. However, the user isn't likely to read through a list of 1000 accounts at a time. It's cases like this where pagination is useful.

Pagination is the process of only displaying a certain range of records to a user at a time. The account list page will only show 12 records at a time. By default, records 1-12 will show. If the user wants to see more they can click the 'next' link. They can then click the 'previous' link to see records already viewed.

This lesson will teach you how to add pagination to the account list view.

Step 1: Update the View

Open the /.../crmeasy/crmapp/accounts/views.py file in your IDE to begin. Add the paginate_by= value as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class AccountList(ListView):
    model = Account
    paginate_by = 12
    template_name = 'accounts/account_list.html'
    context_object_name = 'accounts'

    def get_queryset(self):
        account_list = Account.objects.filter(owner=self.request.user)
        return account_list

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(AccountList, self).dispatch(*args, **kwargs)

Code Review

Line 3: This is the only change to the AccountList() view. It limits the queryset to 12 records at a time.

Step 2: Update the Template

Open the /.../crmeasy/crmapp/templates/accounts/account_list.html file in your IDE for editing. Locate the {# Pagination Section #} comment and add this code beneath it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{# Pagination Section #}
{% if is_paginated %}
    <div id="al-paginate">
        <ul class="strip-list al-pgnt-list">
            {% if page_obj.has_previous %}
                <li class="pull-left">
                    <a href="{% url 'account_list' %}?page={{ page_obj.previous_page_number }}
                    {% if request.GET.account %}&account={{ request.GET.account }}{% endif %}">Prev</a>
                </li>
            {% endif %}
            {% if page_obj.has_next %}
                <li class="pull-right">
                    <a href="{% url 'account_list' %}?page={{ page_obj.next_page_number }}
                    {% if request.GET.account %}&account={{ request.GET.account }}{% endif %}">Next</a>
                </li>
            {% endif %}
        </ul>
    </div>
{% endif %}

Code Review

Lines 10-27: First, the {% if is_paginated %} decides whether to show any paginate functionality. The ListView CBV is responsible for setting this value to True if there are more than 12 records; otherwise it will be False.

If there are paginated items, then this code needs to know whether to show the 'Previous' and/or 'Next' links. It will show the 'Next' link if there are more than 12 accounts. It will show the 'Previous' link if the user has navigated away from the 1st page of accounts (or higher).

You can test this functionality by adding more than 12 accounts. Once you've done that, display the page and use the links to navigate around the list.

Step 3: Commit Changes

Execute these commands to commit your changes in Git.

1
2
3
4
5
# add files
(venv)$ git add .

# commit files
(venv)$ git commit -m "added pagination to account list"

Track your progress with a free account