Browse files

Autopaginate tag for paginating directly in templates.

Tests for autopaginate tag.
  • Loading branch information...
1 parent aecd124 commit d0045222e4cb274bfad0fbfa9e220d8b77714d27 @nigma committed Jun 8, 2012
Showing with 59 additions and 17 deletions.
  1. +38 −5 infinite_pagination/templatetags/infinite_pagination.py
  2. +4 −6 tests/templates/auto_list.html
  3. +10 −4 tests/tests.py
  4. +2 −1 tests/urls.py
  5. +5 −1 tests/views.py
View
43 infinite_pagination/templatetags/infinite_pagination.py
@@ -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:
View
10 tests/templates/auto_list.html
@@ -1,4 +1,4 @@
-{% load infinite_pagination_tags %}
+{% load infinite_pagination %}
<!DOCTYPE html>
<html>
<head>
@@ -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>
View
14 tests/tests.py
@@ -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))
@@ -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)
@@ -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/"
View
3 tests/urls.py
@@ -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()),
)
View
6 tests/views.py
@@ -1,5 +1,4 @@
#-*- coding: utf-8 -*-
-
from django.views.generic.list import ListView
from infinite_pagination.paginator import InfinitePaginator
@@ -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.