Over time (plus diligent writing!) Your blog posts will be more and more. If not processed, the same page may be crowded with hundreds of articles, not only ugly, but also reduce the response speed of the page.

This is when the article needs to be paginated.

Use of the wheel

Writing a complete pagination function is a bit of a challenge, but Django already has a ready-made pagination module for you (Django takes care of most of the basics for you!). . The built-in modules are simple but sufficient for blogs.

What we’re going to use is the Paginator class. Try it out in a Shell:

>>> from django.core.paginator import Paginator
>>> objects = ['john'.'paul'.'george'.'ringo']
>>> p = Paginator(objects, 2)

>>> p.count
4
>>> p.num_pages
2
>>> p.page_range
range(1.3)

>>> page1 = p.page(1)
>>> page1
<Page 1 of 2>
>>> page1.object_list
['john'.'paul']

>>> page2 = p.page(2)
>>> page2.object_list
['george'.'ringo']
>>> page2.has_next()
False
>>> page2.has_previous()
True
>>> page2.has_other_pages()
True
>>> page2.previous_page_number()
1
Copy the code

This is an example from the official website. See: Pagination

With this class, all that remains is to apply it to your project.

Get familiar

To paginate the article list, modify the def article_list() view of article/views.py:

article/views.py

...
# introduce paging module
from django.core.paginator import Paginator

def article_list(request):
    Articles -> article_list
    article_list = ArticlePost.objects.all()

    Display 1 article per page
    paginator = Paginator(article_list, 1)
    Get the page number in the URL
    page = request.GET.get('page')
    Return the corresponding page number of the navigation object to articles
    articles = paginator.get_page(page)

    context = { 'articles': articles }
    return render(request, 'article/list.html', context)

...
Copy the code

Using the Paginator class in the view, we manipulate what we pass to the template: Instead of returning a collection of all articles, we return an object for a subset of articles that correspond to the page number, and that object also contains the pagination method.

We’ve already touched on some of the ways to pass parameters to views in previous articles:

  • Form data is passed to the view through a POST request
  • Pass the parameters in the address to the view via the URL

Another approach is used here: in the GET request, enclose the url with? Request.GET. GET (‘key’); request.

Then rewrite the template and add the pagination at the end of :

templates/article/list.html

...

<! -- Page navigation -->
<div class="pagination row">
    <div class="m-auto">
        <span class="step-links">
            <! -- If it is not the first page, display the up button -->
            {% if articles.has_previous %}
                <a href="? page=1" class="btn btn-success">
                    &laquo; 1
                </a>
                <span>.</span>
                <a href="? page={{ articles.previous_page_number }}" 
                   class="btn btn-secondary"
                >
                    {{ articles.previous_page_number }}
                </a>
            {% endif %}

            <! -- Current page -->
            <span class="current btn btn-danger btn-lg">
                {{ articles.number }}
            </span>

            <! -- Display scroll down button if not the last page -->
            {% if articles.has_next %}
                <a href="? page={{ articles.next_page_number }}"
                   class="btn btn-secondary"
                >
                    {{ articles.next_page_number }}
                </a>
                <span>.</span>
                <a href="? page={{ articles.paginator.num_pages }}"
                   class="btn btn-success"
                >
                    {{ articles.paginator.num_pages }} &raquo;
                </a>
            {% endif %}
        </span>
    </div>
</div>.Copy the code

The content is also relatively simple, using some of the methods demonstrated in the previous Shell to determine where the current page is.

That’s it! Supplement a few articles (the author altogether 6), convenient test. After refreshing the page, it looks like this:

The view is set to have only 1 article per page, so there is really only 1 article.

Of course, this is just for testing purposes, but it will be much bigger in the real world.

Click the button on page 2 and it looks like this:

See the change in the address bar at the top?

Think about how pages are passed from templates to views.

conclusion

With the exception of the template, we only wrote four lines of code and we had a decent pagination navigation, which is how nice Django is.

In addition to the list of articles, you can use this module for any pagination you want (for example, comments below) to meet a variety of user needs.

You can also read the Bootstrap 4 documentation and adapt the look to your taste.


  • If you have any questions please leave a message on Doucet’s personal website and I will reply as soon as possible.
  • Or Email me a private message: [email protected]
  • Project code: Django_blog_tutorial

Please indicate the source for reprinting.