djangoのページング機能の使い方が変わったようなので、
それに合わせてページリンクを表示する機能を作った。
また使いそうなので保管。
以前のバージョンで使用していた、BetterPaginatorを参考にした。
http://d.hatena.ne.jp/piro_suke/20070827/1188202390
project_dir/utils.py
import string from django.core.paginator import Page, InvalidPage class BetterPage(Page): def __init__(self, page, link_template): self.link_template = link_template Page.__init__(self, page.object_list, page.number, page.paginator) def previous_link(self): if self.has_previous(): tpl = string.Template(self.link_template) return tpl.safe_substitute({"page": self.number - 1}) else: return None def next_link(self): if self.has_next(): tpl = string.Template(self.link_template) return tpl.safe_substitute({"page": self.number + 1}) else: return None def make_page_links(self, start, end): tpl = string.Template(self.link_template) return [(p+1, tpl.safe_substitute({"page": p + 1}), (p+1 == self.number)) for p in range(start, end)] def page_links(self): return self.make_page_links(0, self.paginator.num_pages) def windowed_page_links(self, window_size=5): links = [] if self.paginator.num_pages <= window_size: links = [self.page_links()] elif self.number - window_size/2 <= 3: links = [self.make_page_links(0, window_size), self.make_page_links(self.paginator.num_pages-2, self.paginator.num_pages)] elif self.number + window_size/2 > self.paginator.num_pages - 2: links = [self.make_page_links(0, 2), self.make_page_links(self.paginator.num_pages-window_size, self.paginator.num_pages)] else: links = [self.make_page_links(0, 2), self.make_page_links(self.number-window_size/2-1, self.number+window_size/2-1), self.make_page_links(self.paginator.num_pages-2, self.paginator.num_pages)] return links
project_dir/urls.py
from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^list/$', 'project_dir.app_dir.views.show_list'), (r'^list/p(?P<page_number>\d+)/$', 'project_dir.app_dir.views.show_list'), (r'^list/user/(?P<user_name>[0-9a-zA-Z_\-])/$', 'project_dir.app_dir.views.show_user_list'), (r'^list/user/(?P<user_name>[0-9a-zA-Z_\-])/p(?P<page_number>\d+)/$', 'project_dir.app_dir.views.show_user_list'), )
project_dir/app_dir/views.py
from django.core.paginator import QuerySetPaginator, InvalidPage from project_dir.utils import * from project_dir.app_dir.models import * def show_list(request, page_number=1): article_list = Article.objects.all() article_paginator = QuerySetPaginator(article_list, 10) article_page = BetterPage(article_paginator.page(page_number), '/list/p${page}/') return render_to_response('article_list.html', {'page': article_page,}, context_instance=RequestContext(request)) # 絞り込み条件付の場合 def show_user_list(request, user_name, page_number=1): article_list = Article.objects.all(user_name=user_name) article_paginator = QuerySetPaginator(article_list, 10) article_page = BetterPage(article_paginator.page(page_number), '/list/user/%s/p${page}/' % (user_name,)) return render_to_response('article_list.html', {'page': article_page,}, context_instance=RequestContext(request))
article_list.html
... {% include "pager.html" %} {% for article in page.object_list %} <h3>{{ article.title }}</h3> {% endfor %} {% include "pager.html" %} ...
pager.html
<div class="paginator"> {% if page.has_previous %} <a class="arrow" href="{{ page.previous_link }}">« 前</a> {% else %} <span class="disabled arrow">« 前</span> {% endif %} {% for s in page.windowed_page_links %} {% if not forloop.first %}<span class="omitted-page">...</span>{% endif %} {% for p in s %} {% if p.2 %} <span class="current-page">{{ p.0 }}</span> {% else %} <a class="other-page" href ="{{ p.1 }}">{{ p.0 }}</a> {% endif %} {% endfor %} {% endfor %} {% if page.has_next %} <a class="arrow" href="{{ page.next_link }}">次 »</a> {% else %} <span class="disabled arrow">次 »</span> {% endif %} <div style="clear: left;"></div> </div>
paginator.css
.paginator { margin: 0 0 10px 0; } .paginator .arrow { display: block; float: left; padding: 5px; margin: 0 5px 0 0; text-decoration: none; color: #00c; } .paginator .disabled { color: #ccc; background-color: #eee; } .paginator .other-page { display: block; float: left; padding: 5px; margin: 0 5px 0 0; text-decoration: none; border: 1px solid #ccc; color: #00c; } .paginator .current-page { display: block; float: left; padding: 5px; margin: 0 5px 0 0; text-decoration: none; border: 1px solid #ccc; color: #00c; font-weight: bold; background-color: #fff; } .paginator .omitted-page { display: block; float: left; padding: 5px; margin: 0 5px 0 0; color: #000; }
まだあまりテストできていないので、データの数が増えると
動かなかったりするかもしれない。