Djangoでページングを表示するための関数
Djangoでページング処理を作成する際に作った関数を紹介します。
コードの紹介になるので、紹介はコードにコメントにて行います。
前後のページを表示するための関数
# self.limit: データ表示数 def page_data(self, count, page): # count: データ数 # page: 現在のページ番号 current_page = page if count == 0 or count < self.limit: # データ数が0の場合に対応 prev_page = 1 next_page = 1 page_limit = 1 else: # ページの最後尾の数値をみつける。 page_num = int(count / self.limit) # 割り切れない場合は+1して、あまりを表示できるようにする page_limit = page_num if count % self.limit == 0 else page_num + 1 # 前のページが1未満にならないようにする prev_page = 1 if (current_page - 1) < 1 else current_page - 1 # 次のページがページ番号の限界を超えないようにする next_page = page_limit if (current_page + 1) > page_limit else current_page + 1 return { 'prev': prev_page, # 前のページ 'current': current_page, # 現在のページ 'next': next_page, # 次のページ 'limit': page_limit, # ページの限界 'next_page': 'home', # {% url next_page %}のように使用する }
テンプレートのコードをなくしてしまったので紹介できません。orz
return
で返しているデータからhtmlタグを作成するとできます。
範囲でページを表示するための関数
もう少しスマートに作成する方法がありそうです。
def get_page_list(self, data_size, current_page): PAGE_RANGE_SIZE = 5 # ページ番号を表示する数 if data_size % self.limit == 0: page_limit = int(data_size / self.limit) else: # 割り切れない場合は+1して、あまりを表示できるようにする page_limit = int(data_size / self.limit) + 1 page_list = [] # ↓ startとendを計算して、あとでループに使用する start = current_page - 2 if start < 1: start = 1 end = start + PAGE_RANGE_SIZE if end > page_limit: end = page_limit + 1 # ↓ を入れないとページ番号がずれる start = end - PAGE_RANGE_SIZE if start < 1: start = 1 # ページ番号を取得する for pi in range(start, end): page_list.append(pi) return { 'current': current_page, # 現在のページ 'limit': page_limit, # ページ番号の限界 'nums': page_list, # ページ番号のリスト 'next_page': 'home', # {% url next_page %}のように使用する }
テンプレートを作成する。
bulmaというcssフレームワークを使用していますが、基本は同じかと思います。
横に長くなってしまって見づらいです。どうにかしたいところです。
<ul class="pagination-list"> {% if page.current != 1 %} <!-- 現在のページが先頭なら表示しない --> <li><a class="pagination-link" href="{% url page.next_page %}?{%query_transform request page=1%}"><<</a></li> {% endif %} {% for num in page.nums %} <li> <!-- 現在のページの場合はクラスを追加する --> <a class="pagination-link {% if num == page.current %} is-current {% endif %}" href="{% url page.next_page %}?{%query_transform request page=num%}">{{num}}</a> </li> {% endfor %} {% if page.current != page.limit %} <!-- 現在のページが最後尾なら表示しない --> <li><a class="pagination-link" href="{% url page.next_page %}?{%query_transform request page=page.limit%}">>></a></li> {% endif %} </ul>
query_transform
というのは独自に作ったtagです。
これを使うと、クエリストリングをスマートに作成できます。
@register.simple_tag def query_transform(request, **kwargs): updated = request.GET.copy() for k, v in kwargs.items(): updated[k] = v return updated.urlencode()
これはどこかの記事で紹介していた気がします。
stackoverflowで載っていたものを使っています。