Djangoでは、表示する項目が多く1ページに収まらないような場合、ページネーション(ページング)という複数ページに表示を分けてくれる機能があります。
ページネーションとよく使われるのが、クラスベースビューのひとつであるListView。
ListViewでは、属性paginated_byを指定するだけで自動でページネーションを有効化してくれます。
一方で、テンプレートでページの情報を使用するときに、どういう情報が使用できるのかを知っておく必要があります。
そこで今回は、djangoのページネーション機能を提供するPaginatorクラスとPageクラスについて、使い方や属性、メソッドの詳細をコード例で確認しながら説明します!
Djangoに必要なHTML/CSS、JavaScriptなどのWeb開発系言語は侍テラコヤという学習サイトで無料で学習できるのでおすすめですよ!
PaginatorクラスとPageクラスの概要
Djangoのページネーションを実現するには、django.core.paginatorで定義されたPaginatorクラスとPageクラスを使用します。
Paginatorクラスはすべてのページを管理するクラスで、Paginatorクラスの各ページを構成するのがPageクラスです。
また、Paginatorクラスで各ページのPageオブジェクトを取得するメソッドが用意されており、Pageクラスのオブジェクトを直接生成することはほとんどないでしょう。
まずはPaginatorクラスのコンストラクタ引数、属性、メソッドを説明し、その次にPageクラスのそれらについて説明します。
また、説明内容は以下のDjangoの公式ドキュメント(英語)を参考にしています。
Paginatorクラス
Paginatorクラスについて、使用できるメソッドや属性の説明を、実際のコード付きで解説します。
django shell(対話形式でdjangoの関数などを実行できる環境)で、ひとつずつコードを実行し、その結果がわかるような形式なので、具体的な関数や属性の返り値もすぐにわかるようにしてみました。
以下のコード例では省略していますが、コードを実行する際には最初に以下のPaginatorのimportを行うことを忘れないようにしてください。
>>> from django.core.paginator import Paginator
Paginatorオブジェクトの生成
まずは、Paginatorオブジェクトを生成する必要があります。
Paginatorクラスは以下のように定義されています。
class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)
コンストラクタ引数をまずはざっくりまとめました。
引数名 | 必須 | 型 | 意味 |
---|---|---|---|
object_list | 必須 | list, tuple, QuerySetなど | ページネーション対象のオブジェクト |
per_page | 必須 | int | 1ページあたりのオブジェクト数 |
orphans | 任意 | int | 最後のページのオブジェクト数がorphans以下のとき、前のページに収める(デフォルト0) |
allow_empty_first_page | 任意 | bool | 最初のページが空でも例外としないか(デフォルトはTrue=例外としない) |
必須パラメータは、object_listとper_pageです。
その他のorphansとallow_empty_first_pageはオプションで、それぞれ指定しない場合はデフォルト値が入ります。
上の表だけだとイメージしづらいと思うので、もう少し詳しく見ていきましょう。
実際のコード例は、後ほど出てきます。
object_list
object_listは、実際にページネーションの対象とするオブジェクトを指定します。
この後紹介するコード例では、簡単にするためにリストを指定していますが、実際にはmodelに保存んしたオブジェクトのリスト(QuerySet)を使用することが多いでしょう。
すべてのオブジェクトをobjects.all()などで取得し、それをこのobject_listとして渡すイメージです。
per_page
per_pageは、1ページあたりのオブジェクト数です。
オブジェクトが全部で5つあった場合、per_pageを2とすると、3ページ(オブジェクト数がそれぞれ2個, 2個, 1個)となりますし、per_pageを3とすると、2ページ(オブジェクト数がそれぞれ3個, 2個)になります。
以下では、オブジェクト数が5のリストに対して、per_pageを2としたときと、3としたときのページ数を実際に出力しています。
後で出ますが、num_pagesはページ数を表す属性です。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi']
>>> p = Paginator(objects, 2)
>>> p.num_pages
3
>>> p = Paginator(objects, 3)
>>> p.num_pages
2
orphans
orphansは、最後のページが中途半端なときに、どうするかを決める値です。
オブジェクトが全部で5つあった場合、per_pageを2とすると、オブジェクト数がそれぞれ2個, 2個, 1個のページができます。
この最後のページの1個は中途半端だから、2ページ目に押し込んじゃえ、というのがorphansの設定です。
orphansは整数を指定し、最後のページのオブジェクト数が、orphans以下のとき、最後のページのオブジェクトをすべて前のページに押し込みます。
デフォルトでは0なので、実質無効化されている状態です。(最後のページが0個以下ということはないので)
以下では、object_listをオブジェクト数が5のリスト、per_pageを2としたときのページ数を実際に出力しています。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi', 'Kaori']
>>> p = Paginator(objects, 2)
>>> p.num_pages
3 # orphansがない場合は、普通に3ページとなる
>>> p = Paginator(objects, 2, orphans=1)
>>> p.num_pages
2 # orphans=1としたので、最後のページのオブジェクトが2ページ目に移動し、全部で2ページとなる
ちなみにorphan(オーファン)というのは、孤児という意味の英単語です。
最終ページのオブジェクトが孤児になった場合、前のページへ合流させるとイメージするといいでしょう。
allow_empty_first_page
allow_empty_first_pageはデフォルトではTrueですが、これがFalseの場合、object_listが空のときに例外が発生します。
ただし、Paginatorオブジェクトの生成の時点では例外は発生しません。
Paginatorオブジェクトを生成後、ページを参照しようとするとEmptyPageという例外が発生します。
後ほど紹介しますが、実際にはこのallow_empty_first_pageとobject_listの検証は、Paginatorクラスのvalidate_numberメソッドで行っているからです。
ページの参照するときに、このvalidate_numberメソッドが呼び出され、最終的に例外となります。
以下は、Paginatorクラスのget_pageメソッドを使って、例外が発生する例です。
>>> p = Paginator([], 1, allow_empty_first_page=True) # 空のobject_listで、Paginatorを生成
>>> p.get_page(1)
<Page 1 of 1> # 問題なく1ページ目のオブジェクトが返る
>>> p = Paginator([], 1, allow_empty_first_page=False) # allow_empty_first_page=Falseで生成(生成自体は成功)
>>> p.get_page(1) # ページを参照しようとすると、EmptyPageエラーが発生
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 71, in get_page
return self.page(number)
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 75, in page
number = self.validate_number(number)
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 52, in validate_number
raise EmptyPage(_("That page number is less than 1"))
django.core.paginator.EmptyPage: <unprintable EmptyPage object>
Paginatorクラスの属性
Paginatorクラスを生成する際の引数について説明しました。
次は、Paginatorクラスのオブジェクトにはどんな属性(インスタンス変数)があるのかを説明します。
まずは表で簡単な説明をまとめたあと、個別にコード例を示しながら解説していきます。
変数名 | 型 | 意味 |
---|---|---|
count | int | オブジェクト数 |
num_pages | int | ページ数 |
page_range | range | ページ範囲(1から始まるrange()オブジェクト) |
ELLIPSIS | django独自クラス | ページ数が多い時の省略記号。デフォルトでは”…”が指定されている。 |
count
Paginatorオブジェクト生成時に渡したobject_listの要素数です。
ページング対象のオブジェクトがいくつあるのか?を返します。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi']
>>> p = Paginator(objects, 2)
>>> p.count
4
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi', 'Kaori']
>>> p = Paginator(objects, 2)
>>> p.count
5
num_pages
ページ数を返します。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi']
>>> p = Paginator(objects, 2)
>>> p.num_pages
3
>>> p = Paginator(objects, 3)
>>> p.num_pages
2
page_range
ページの範囲を、1から始まるrange()オブジェクト形式で返します。
実際のdjangoの実装では、以下のように、1〜ページ数の範囲になるようなrangeオブジェクトが設定されています。
def page_range(self):
return range(1, self.num_pages + 1)
具体例は、以下の通りです。
>>> p = Paginator(objects, 2) # 3ページの場合
>>> p.page_range
range(1, 4)
>>> p = Paginator(objects, 3) # 2ページの場合
>>> p.page_range
range(1, 3)
ELLIPSIS
ページ数が多い時の省略記号です。
デフォルトでは3点リーダー(…)が設定されています。
以下では、10個のオブジェクトを、1オブジェクトごとにペーンジングするときに省略記号が出力される例です。
後で説明しますが、以下ではget_elided_page_range()メソッドを使って、ページ数と省略記号を組み合わせて、ページ番号を出力しています。
実際使用するときは、ブラウザ表示するときに自動で呼び出されるので、コード例の意味がわからなくても気にしなくてよいです。(無理にELLIPSISの動きを確認しようとしているだけなので!)
>>> objects = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> p = Paginator(objects, 1)
>>> elided_page_range = p.get_elided_page_range(5, on_each_side=1, on_ends=1) # get_elided_page_rangeの返り値を取得
>>> [page for page in elided_page_range] # ジェネレータから要素を抜き出す
[1, '…', 4, 5, 6, '…', 10]
ちなみに、ELLIPSISを別の記号にすることも可能です。
>>> p.ELLIPSIS = "-"
>>> [page for page in p.get_elided_page_range(5, on_each_side=1, on_ends=1)]
[1, '-', 4, 5, 6, '-', 10]
Paginatorクラスのメソッド
続いてPaginatorクラスのメソッドを説明します。
実際には、Djangoが内部で自動的にいろいろ呼び出してくれるので、基本的にはあまり意識しなくてもよいです。
ただ、メソッドの中身を知っていれば、何か不具合が起きた時の原因調査や、手の込んだことをやりたいときにどの関数を改造(オーバーライド)すればいいのか?を考えるときに役に立ちます。
例によって、先に表でまとめて、その後個別に詳しく見ていきましょう。(表の確認だけでもOKです)
メソッド名 | 引数 | 戻り値 | 説明 |
---|---|---|---|
get_page | ページ番号 | Pageオブジェクト | 指定したページ番号のPageオブジェクトを返す(異常値を許容) |
page | ページ番号 | Pageオブジェクト | 指定したページ番号のPageオブジェクトを返す(異常値は例外) |
get_elided_page_range | ページ番号 指定ページの両側のページ(任意) 両端のページ数 (任意) | ジェネレータ | 指定したページを中心とした、ページ全体の表示 |
get_page(number)
Paginatorオブジェクトの各ページは、Pageクラスという別のクラスのオブジェクトで構成されています。
Pageオブジェクトについては後で説明しますが、Paginatorオブジェクトの各ページごとに生成され、各ページに含まれるオブジェクトのリストや、ページ番号などを所持しています。
get_pageメソッドは、このPageオブジェクトを返すメソッドです。
引数のnumberは、取得したいPageオブジェクトのページ番号を指定します。
特徴としては、数字以外の値を引数で渡すと最初のページのPageオブジェクトを返し、負の値や最終ページ番号より大きい値を渡すと最終ページのPageオブジェクトを返します。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi', 'Kaori']
>>> p = Paginator(objects, 2)
>>> p.num_pages # ページ数が3のPaginatorオブジェクトの生成
3
>>> p.get_page(2) # 2ページ目のPageオブジェクトを返す
<Page 2 of 3>
>>> p.get_page(5) # ページ数より大きい値のときは最終ページのPageオブジェクトを返す
<Page 3 of 3>
>>> p.get_page('Taro') # 数値以外のときは最初のページのPageオブジェクトを返す
<Page 1 of 3>
Paginatorオブジェクト生成時にallow_empty_first_pageがFalseで、空のオブジェクトをobjects_listに指定している場合は、EmptyPage例外がraiseされます。
>>> p = Paginator([], 2, allow_empty_first_page=False) # 空オブジェクトに対してallow_empty_first_pageをFalseで設定
>>> p.get_page(1)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 71, in get_page
return self.page(number)
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 75, in page
number = self.validate_number(number)
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 52, in validate_number
raise EmptyPage(_("That page number is less than 1"))
django.core.paginator.EmptyPage: That page number is less than 1
page(number)
pageメソッドは、 先ほどのget_pageメソッドと同じで、引数に指定したページ番号のPageオブジェクトを返します。
get_pageメソッドとの違いは、整数以外の値や、存在しないページ数を引数に指定した場合に例外が発生する点です。
メソッド名 | 引数が整数以外 | 引数が存在しないページ番号 |
---|---|---|
get_page | 最初のページのPageオブジェクトを返す | 最後のページのPageオブジェクトを返す |
page | PageNotAnInteger例外 | EmptyPage例外 |
ちなみに、「整数以外」というのは、厳密には「Pythonのint()メソッドで整数に変換できない」場合なので、’1’のような文字列でもintにキャストできる場合は、そのページ番号のPageオブジェクトが返ります。
また、「存在しないページ番号」は、最大ページ数より大きい値のほか、負の値や少数も含みます。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi', 'Kaori']
>>> p = Paginator(objects, 2)
>>> p.page(2) # 存在するページ番号であればPageオブジェクトを返す
<Page 2 of 3>
>>> p.page('Taro') # 数値以外の場合は PageNotAnInteger 例外発生
Traceback (most recent call last):
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 48, in validate_number
number = int(number)
ValueError: invalid literal for int() with base 10: 'Taro'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 75, in page
number = self.validate_number(number)
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 50, in validate_number
raise PageNotAnInteger(_("That page number is not an integer"))
django.core.paginator.PageNotAnInteger: That page number is not an integer
>>> p.page(5) # 存在しないページ番号場合は EmptyPage 例外発生
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 75, in page
number = self.validate_number(number)
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 52, in validate_number
raise EmptyPage(_("That page number is less than 1"))
django.core.paginator.EmptyPage: That page number is less than 1
get_elided_page_range(number, *, on_each_side=3, on_ends=2)
最後は、Paginatorクラスの属性ELLIPSISの説明で少し出ましたが、get_elided_page_rangeメソッドです。
引数numberに指定したページ番号を中心とした、ページ全体の番号のリストを取得できます。
引数on_each_sideは、指定したページ番号の両側の何ページまで表示するかを指定する引数です。
引数on_endsは、全体の両端で表示させるページ数を指定します。
number, on_each_side, on_endsで表示しきれない部分が省略記号(デフォルトでは3点リーダー(…))になります。
細かい話になりますが、get_elided_page_rangeはジェネレータを返すので、メソッドを呼び出した後にfor文などで中身を取り出す必要があります。
さらにちなみに、メソッド引数にアスタリスク(*)が単体でありますが、これはそれ以降の引数はキーワード引数(on_each_side=3のように引数名=値という指定方法)でしか使用できないようにするための機能です。
>>> objects = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> p = Paginator(objects, 1)
>>> elided_page_range = p.get_elided_page_range(5) # numberだけを指定(残りの引数はデフォルト)
>>> [page for page in elided_page_range]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> elided_page_range = p.get_elided_page_range(4, on_each_side=1) # on_each_sideを1にしたので、4の前後1つだけ表示
>>> [page for page in elided_page_range]
[1, 2, 3, 4, 5, '…', 9, 10]
>>> elided_page_range = p.get_elided_page_range(6, on_each_side=1, on_ends=1) # on_endsを1にしたので、両端は1つだけ表示
>>> [page for page in elided_page_range]
[1, '…', 5, 6, 7, '…', 10]
Pageクラス
Paginatorオブジェクの各ページは、Pageオブジェクトで構成されています。
Paginatorオブジェクトが親、Pageオブジェクトが子のような関係をイメージするといいでしょう。
Paginatorクラスのget_pageメソッドや、pageメソッドでは、指定したページ番号のPageオブジェクトを取得できましたよね。
PageオブジェクトはPaginatorオブジェクトのget_pageメソッドなどで自動的に生成されるので、Pageオブジェクトを個別に生成することはほとんどないかと思います。(Djangoの公式にもそのように記載されています)
ただ、どんな属性があって、どんなメソッドが使用できるのか?を知ることで、テンプレートでどういう情報を使えるのかを把握しておくことができます。
ちなみに、PageオブジェクトはPaginatorクラスのpageメソッド以外にも、Paginatorオブジェクトをfor文などでイテレートしても取得できます。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi', 'Kaori']
>>> p = Paginator(objects, 2)
>>> [page for page in p] # Paginatorオブジェクトをfor文でイテレーション
[<Page 1 of 3>, <Page 2 of 3>, <Page 3 of 3>]
Pageオブジェクトの生成
繰り返しになりますが、PageオブジェクトはPaginatorオブジェクトでget_pageなどでページを取得する時に自動で作られるので、生成方法を詳しく知っておく必要はあまりないかもしれません。
ただ、知識として知っておいて損はないでしょう。
Djangoでは、Pageクラスは以下のように定義されています。
class Page(object_list, number, paginator)
コンストラクタ引数はすべて必須パラメータで、以下のような意味があります。
引数名 | 必須 | 型 | 意味 |
---|---|---|---|
object_list | 必須 | list, tuple, QuerySetなど | そのページ内のオブジェクト |
number | 必須 | int | ページ番号 |
paginator | 必須 | int | 所属しているPaginatorオブジェクト |
object_listは、Paginatorのobject_listのうち、そのページに属する部分のリストです。
numberは、そのPageオブジェクトのページ番号を指定します。
paginatorは、そのPageオブジェクトが属するPaginatorオブジェクト(親)のインスタンスです。
ちなみに、Paginatorのpageメソッドでは、以下のような引数でPageオブジェクトを生成して返却しています。(分かりやすいように一部加工しています)
def page(self, number):
bottom = オブジェクトの中でのそのページの最初の要素番号
top = bottom + self.per_page # bottom + 1ページあたりのオブジェクト数 = そのページの最後のオブジェクト番号
Page(self.object_list[bottom:top], number, self)
Pageクラスの属性
Pageクラスの属性は、Pageクラスのコンストラクタ引数と同じです。
表だけ再掲しますが、詳細は割愛します。
引数名 | 型 | 意味 |
---|---|---|
object_list | list, tuple, QuerySetなど | そのページ内のオブジェクト |
number | int | ページ番号 |
paginator | int | 所属しているPaginatorオブジェクト |
Pageクラスのメソッド
Pageクラスのメソッドは、前後のページの有無やページ番号、ページ内のオブジェクト番号を取得するメソッドが用意されています。
これらのメソッドは、ブラウザでページ表示をする際に、テンプレート内のテンプレートタグとして利用することがあるかもしれません。
メソッド名 | 引数 | 戻り値 | 説明 |
---|---|---|---|
has_next | なし | True/ False | 次のページが存在すればTrueを返す |
has_previous | なし | True/ False | 前のページが存在すればTrueを返す |
has_other_pages | なし | True/ False | 次のページまたは前のページが存在すればTrueを返す |
next_page_number | なし | ページ番号 | 次のページのページ番号を返す |
next_page_previous | なし | ページ番号 | 前のページのページ番号を返す |
start_index | なし | オブジェクト番号 | ページ内の最初のオブジェクト番号 |
end_index | なし | オブジェクト番号 | ページ内の最後のオブジェクト番号 |
has_next、has_previous
has_next、has_previousメソッドは、それぞれPageオブジェクトの前または後にページがあるかどうかを判定するためのメソッドです。
前または後のページがあればTrue、なければFalseを返します。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi', 'Kaori']
>>> p = Paginator(objects, 2)
>>> page2 = p.page(2) # 2ページ目のPageオブジェクトを取得
>>> page2.has_next() # 2ページ目の次のページがあるか?(3ページ目があるのでTrue)
True
>>> page2.has_previous() # 2ページ目の前のページがあるか?(1ページ目があるのでTrue)
True
>>> p.page(3).has_next() # 3ページ目の次のページがあるか?(3ページが最終ページなのでFalse)
False
has_other_pages
has_other_pagesは、Pageオブジェクトの前後のどちらかにページが存在すればTrueを返します。
has_nextとhas_previousのどちらかがTrueであれば、Trueになるイメージです。(Djangoでの実装も、self.has_previous() or self.has_next()で定義されています)
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi', 'Kaori']
>>> p = Paginator(objects, 2)
>>> p.page(3).has_other_pages() # 3ページ目の前または次のページがあるか?(前ページがあるのでTrue)
True
next_page_number、previous_page_number
next_page_number、previous_page_numberメソッドは、それぞれ次、前のページのページ番号を返します。
それぞれ、次または前のページが存在しない場合は、InvalidPage例外が放出されるので気をつけましょう。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi', 'Kaori']
>>> p = Paginator(objects, 2)
>>> p.page(2).next_page_number() # 2ページ目の次のページ番号は?
3
>>> p.page(2).previous_page_number() # 2ページ目の前のページ番号は?
1
>>> p.page(3).next_page_number() # 3ページ目の次のページ番号は?(3ページの次はないのでInvalidPageエラー)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 201, in next_page_number
return self.paginator.validate_number(self.number + 1)
File "/Users/Toshiki/.pyenv/versions/3.9.13/lib/python3.9/site-packages/django/core/paginator.py", line 57, in validate_number
raise EmptyPage(_("That page contains no results"))
django.core.paginator.EmptyPage: That page contains no results
start_index、end_index
start_index、end_indexは、Paginatorに渡されたobject_listのうち、そのページ内の最初の要素番号または最後の要素番号を返します。
ただし、普通のリストのインデックス番号とは違い、1から始まる点には気をつけましょう。
ページ番号と揃えるためかと思います。
>>> objects = ['Taro', 'Hanako', 'Jiro', 'Takashi', 'Kaori']
>>> p = Paginator(objects, 3)
>>> p.page(1).start_index()
1
>>> p.page(1).end_index()
3
まとめ
今回はDjangoのページネーションを実現するPaginatorとPageクラスについて説明しました。
Djangoのページネーションは便利ですが、テンプレートにどのように変数を使用したらいいのだろう、と思うことがあるかもしれません。
他のサイトなどで紹介されているページネーション用のテンプレートHTMLの内容をコピペでもいいですが、内容を理解して使いたい方や、カスタマイズしたい方はぜひ参考にしてください。
なお、侍テラコヤという学習サイトでは、DjangoをはじめPythonやHTML/CSS/JavaScriptを無料で学ぶことができます!
メールアドレスだけで簡単に無料登録できるのでぜひ覗いてみてくださいね。
\無料プランを無期限で試す/
メールアドレスだけで10秒で登録!
ページネーションの例は、以下のListViewの説明のところでも紹介しているので、あわせて参照してもらえればと思います。
Djangoはまだまだたくさんの機能が盛り沢山です。
このサイトでは、他にもさまざまな解説記事を載せているので、ぜひ参考にしてください!
また、独学だけでなく、人から教えてもらうというのも大切です。
以下の記事ではDjangoが学べるプログラミングスクールを紹介していますので、こちらもぜひご検討ください。
コメント