ページ送りとは,ページネーションと呼ばれ,複数の要素をページごとにわけて表示することです
何も対策していないと,1ページにデータベースの中身全てを出力することになり,サーバーへのアクセスがパンパンになってアンパンマンになります
本記事では,ListViewでデータベースの中身を出力する際に,ページ送りを実装する方法について解説します
ListViewの基本的な使い方は下記記事を参照してください
【django】ListViewでデータベースの中身を表示する方法
djangoのデータベースをうまく扱えないと悩んだことはないでしょうか? djangoではListViewを用いることで簡単にデータベースを扱うことができます 本記事では,ListVie…
目次
ListViewのpagenated_byでページネーションの要素数を指定する
ListViewでは,クラス変数にページごとに表示する要素数を簡単に指定できます
クラス変数にpaginated_byを追加し,要素数を数値で指定してください
class BlogListView(ListView):
model = Blog
template_name = 'blog/blog.html'
context_object_name = 'results'
paginate_by = 3
ページ送りを実装するTemplateを準備する
直接実装したいテンプレートに書いても良いですが,長くなるので専用のものを用意します
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-primary mb-4" href="?page=1">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="24" fill="currentColor" class="bi bi-skip-start" viewBox="0 0 16 16">
<path d="M4 4a.5.5 0 0 1 1 0v3.248l6.267-3.636c.52-.302 1.233.043 1.233.696v7.384c0 .653-.713.998-1.233.696L5 8.752V12a.5.5 0 0 1-1 0V4zm7.5.633L5.696 8l5.804 3.367V4.633z"/>
</svg>
</a>
<a class="btn btn-outline-primary mb-4" href="?page={{page_obj.previous_page_number}}">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="24" fill="currentColor" class="bi bi-caret-left" viewBox="0 0 16 16">
<path d="M10 12.796V3.204L4.519 8 10 12.796zm-.659.753l-5.48-4.796a1 1 0 0 1 0-1.506l5.48-4.796A1 1 0 0 1 11 3.204v9.592a1 1 0 0 1-1.659.753z"/>
</svg>
</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-primary mb-4" href="?page={{num}}">{{ num }}</a>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a class="btn btn-outline-primary mb-4" href="?page={{num}}">{{ num }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a class="btn btn-outline-primary mb-4" href="?page={{page_obj.next_page_number}}">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="24" fill="currentColor" class="bi bi-caret-right" viewBox="0 0 16 16">
<path d="M6 12.796V3.204L11.481 8 6 12.796zm.659.753l5.48-4.796a1 1 0 0 0 0-1.506L6.66 2.451C6.011 1.885 5 2.345 5 3.204v9.592a1 1 0 0 0 1.659.753z"/>
</svg>
</a>
<a class="btn btn-outline-primary mb-4" href="?page={{page_obj.paginator.num_pages}}">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="24" fill="currentColor" class="bi bi-skip-end" viewBox="0 0 16 16">
<path d="M12.5 4a.5.5 0 0 0-1 0v3.248L5.233 3.612C4.713 3.31 4 3.655 4 4.308v7.384c0 .653.713.998 1.233.696L11.5 8.752V12a.5.5 0 0 0 1 0V4zM5 4.633L10.804 8 5 11.367V4.633z"/>
</svg>
</a>
{% endif %}
{% endif %}
用意した上記のpagination.htmlをListViewで使用しているテンプレートにincludeします
本記事ではblog.htmlに実装します
{% block main %}
<div class="text-center mb-5">
<h1 class="display-3 mb-5">はやてれおのBlog</h1>
<p class="text-muted fs-3">Blogの記事一覧</p>
</div>
<div>
{% for result in results %}
<h4>{{ result.title }}</h4>
<p>{{ result.created_at }}</p>
<p class="lead">{{ result.content }}</p>
{% endfor %}
</div>
{% include 'blog/pagination.html' %} <!--追加-->
{% endblock %}
ページ送りの動作確認
では動作を確認しましょう
下記コマンドを実行してサーバーを立ち上げて確認してみてください
python manage.py runserver
参考文献
Pagination | Django documentation
The web framework for perfectionists with deadlines.
お疲れ様でした
コメント