Skip to content

Commit

Permalink
Autopaginate tag for paginating directly in templates.
Browse files Browse the repository at this point in the history
Tests for autopaginate tag.
  • Loading branch information
nigma committed Jun 8, 2012
1 parent aecd124 commit d004522
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 17 deletions.
43 changes: 38 additions & 5 deletions infinite_pagination/templatetags/infinite_pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,64 @@
from __future__ import absolute_import
import copy

from django.core.paginator import InvalidPage
from django.http import Http404
from django.template import Library
from django.utils.translation import ugettext as _

from ..paginator import InfinitePaginator

register = Library()

PAGE = "page"
PAGE_VAR = "page"

@register.assignment_tag(takes_context=True)
def autopaginate(context, object_list, per_page=15, page=None):
"""
Takes a queryset and returns page slice.
It also sets context ``paginator`` and ``page_obj`` variables for purpose
of pagination links rendering.
"""

page_number = page or context.get(PAGE_VAR)
if "request" in context and not page_number:
request = context["request"]
page_number = request.GET.get(PAGE_VAR)
page_number = page_number or 1

try:
page_number = int(page_number)
except ValueError:
raise Http404(_(u"Page can not be converted to an int."))

paginator = InfinitePaginator(object_list=object_list, per_page=per_page)
try:
page_obj = paginator.page(page_number)
except InvalidPage:
raise Http404(_(u"Invalid page (%(page_number)s)") % {"page_number": page_number})

context.update({
"paginator": paginator,
"page_obj": page_obj
})
return page_obj.object_list


@register.inclusion_tag("pagination/infinite_pagination.html", takes_context=True)
def paginate(context):
try:
paginator = context["paginator"]
page_obj = context["page_obj"]
except KeyError:
return {}
assert isinstance(paginator, InfinitePaginator)

tag_context = copy.copy(context) # reuse original context
tag_context["is_paginated"] = page_obj.has_other_pages()

if "request" in context:
getvars = context["request"].GET.copy()
if PAGE in getvars:
del getvars[PAGE]
if PAGE_VAR in getvars:
del getvars[PAGE_VAR]
if len(getvars.keys()) > 0:
tag_context["getvars"] = "&%s" % getvars.urlencode()
else:
Expand Down
10 changes: 4 additions & 6 deletions tests/templates/auto_list.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load infinite_pagination_tags %}
{% load infinite_pagination %}
<!DOCTYPE html>
<html>
<head>
Expand All @@ -7,14 +7,12 @@
<body>
<div>
<ul>
{% autopaginate object_list 10 %}
{% for object in object_list %}
{% autopaginate object_list per_page=10 as paginated_list %}
{% for object in paginated_list %}
<li>{{ object }}</li>
{% endfor %}
</ul>
<div>
{% infinite_paginate %}
</div>
{% paginate %}
</div>
</body>
</html>
14 changes: 10 additions & 4 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def test_empty_page(self):

class TemplateTagTestCase(TestCase):

BASE_URL = "/articles/"
def setUp(self):
for x in range(25):
Article.objects.create(title=str(x))
Expand All @@ -88,23 +89,23 @@ def tearDown(self):
Article.objects.all().delete()

def test_init_page(self):
resp = self.client.get("/articles/?param=x")
resp = self.client.get(self.BASE_URL + "?param=x")
self.assertIn("""<a>&larr; Previous</a>""", resp.content)
self.assertIn("""<a href="?page=2&amp;param=x">Next &rarr;</a>""", resp.content)
self.assertIn("""<li>0</li>""", resp.content)
self.assertNotIn("""<li>10</li>""", resp.content)
self.assertNotIn("""<li>20</li>""", resp.content)

def test_first_page(self):
resp = self.client.get("/articles/?page=1&param=x")
resp = self.client.get(self.BASE_URL + "?page=1&param=x")
self.assertIn("""<a>&larr; Previous</a>""", resp.content)
self.assertIn("""<a href="?page=2&amp;param=x">Next &rarr;</a>""", resp.content)
self.assertIn("""<li>0</li>""", resp.content)
self.assertNotIn("""<li>10</li>""", resp.content)
self.assertNotIn("""<li>20</li>""", resp.content)

def test_second_page(self):
resp = self.client.get("/articles/?page=2&param=x")
resp = self.client.get(self.BASE_URL + "?page=2&param=x")
self.assertIn("""<a href="?page=1&amp;param=x">First</a>""", resp.content)
self.assertIn("""<a href="?page=1&amp;param=x">&larr; Previous</a>""", resp.content)
self.assertIn("""<a href="?page=3&amp;param=x">Next &rarr;</a>""", resp.content)
Expand All @@ -113,9 +114,14 @@ def test_second_page(self):
self.assertNotIn("""<li>20</li>""", resp.content)

def test_last_page(self):
resp = self.client.get("/articles/?page=3&param=x")
resp = self.client.get(self.BASE_URL + "?page=3&param=x")
self.assertIn("""<a href="?page=1&amp;param=x">First</a>""", resp.content)
self.assertIn("""<a href="?page=2&amp;param=x">&larr; Previous</a>""", resp.content)
self.assertIn("""<a>Next &rarr;</a>""", resp.content)
self.assertIn("""<li>20</li>""", resp.content)
self.assertNotIn("""<li>10</li>""", resp.content)


class AutoPaginateTemplateTagTestCase(TemplateTagTestCase):

BASE_URL = "/auto/"
3 changes: 2 additions & 1 deletion tests/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

from django.conf.urls import patterns, url

from .views import ArticleListView
from .views import ArticleListView, AutoArticleListView

urlpatterns = patterns("",
url(r"^articles/", ArticleListView.as_view()),
url(r"^auto/", AutoArticleListView.as_view()),
)
6 changes: 5 additions & 1 deletion tests/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#-*- coding: utf-8 -*-

from django.views.generic.list import ListView

from infinite_pagination.paginator import InfinitePaginator
Expand All @@ -12,3 +11,8 @@ class ArticleListView(ListView):
paginate_by = 10
paginator_class = InfinitePaginator
template_name = "article_list.html"


class AutoArticleListView(ListView):
model = Article
template_name = "auto_list.html"

0 comments on commit d004522

Please sign in to comment.