From 3c0326b47c77e76b0c07cdf985cde392083711a0 Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Thu, 31 Jul 2014 22:09:23 +0200 Subject: [PATCH 01/11] Django 1.7 compatibility hotfix --- pagination/paginator.py | 20 ++++++++++++++++++++ pagination/templatetags/pagination_tags.py | 7 +++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/pagination/paginator.py b/pagination/paginator.py index f67aa23..23faf27 100644 --- a/pagination/paginator.py +++ b/pagination/paginator.py @@ -1,5 +1,25 @@ from django.core.paginator import Paginator, Page, PageNotAnInteger, EmptyPage + +class ConcretePaginator(Paginator): + """ + Fix on the Django paginator that now uses an xrange, which isn't + compatible with the slicing that goes on in the template tags here. + """ + + def _get_page_range(self): + """ + Returns a 1-based range of pages for iterating through within + a template for loop. + """ + r = super(ConcretePaginator, self)._get_page_range() + if not isinstance(r, list): + r = list(r) + return r + page_range = property(_get_page_range) + + + class InfinitePaginator(Paginator): """ Paginator designed for cases when it's not important to know how many total diff --git a/pagination/templatetags/pagination_tags.py b/pagination/templatetags/pagination_tags.py index 1d544f0..93323bd 100644 --- a/pagination/templatetags/pagination_tags.py +++ b/pagination/templatetags/pagination_tags.py @@ -6,9 +6,12 @@ from django import template from django.template import TOKEN_BLOCK from django.http import Http404 -from django.core.paginator import Paginator, InvalidPage +from django.core.paginator import InvalidPage from django.conf import settings +from pagination.paginator import ConcretePaginator + + register = template.Library() DEFAULT_PAGINATION = getattr(settings, 'PAGINATION_DEFAULT_PAGINATION', 20) @@ -99,7 +102,7 @@ def render(self, context): paginate_by = self.paginate_by else: paginate_by = self.paginate_by.resolve(context) - paginator = Paginator(value, paginate_by, self.orphans) + paginator = ConcretePaginator(value, paginate_by, self.orphans) try: page_obj = paginator.page(context['request'].page(page_suffix)) except InvalidPage: From e798bc8c04001888d7bbd2134439f8532ba50e67 Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Sat, 21 Feb 2015 12:05:28 -0800 Subject: [PATCH 02/11] Fix invalid syntax (breaks on Python 3) Fixed in upstream development branch as well: https://github.com/ericflo/django-pagination/commit/c2ec7c52d1d50131e92e82ccb30814fdd389f8f6 https://code.google.com/p/django-pagination/issues/detail?id=8 --- pagination/templatetags/pagination_tags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pagination/templatetags/pagination_tags.py b/pagination/templatetags/pagination_tags.py index 93323bd..839b500 100644 --- a/pagination/templatetags/pagination_tags.py +++ b/pagination/templatetags/pagination_tags.py @@ -242,7 +242,7 @@ def paginate(context, window=DEFAULT_WINDOW, hashtag=''): else: to_return['getvars'] = '' return to_return - except KeyError, AttributeError: + except (KeyError, AttributeError): return {} register.inclusion_tag('pagination/pagination.html', takes_context=True)( From fc71f48d8d4656644c15919b7564d6b7a567ad6f Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Sat, 21 Feb 2015 12:26:47 -0800 Subject: [PATCH 03/11] Fix filter expression for Python 3 --- pagination/templatetags/pagination_tags.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pagination/templatetags/pagination_tags.py b/pagination/templatetags/pagination_tags.py index 839b500..4e03f80 100644 --- a/pagination/templatetags/pagination_tags.py +++ b/pagination/templatetags/pagination_tags.py @@ -24,12 +24,12 @@ def do_autopaginate(parser, token): """ Splits the arguments to the autopaginate tag and formats them correctly. """ - # Check whether there are any other autopaginations are later in this template expr = lambda obj: (obj.token_type == TOKEN_BLOCK and \ len(obj.split_contents()) > 0 and obj.split_contents()[0] == "autopaginate") - multiple_paginations = len(filter(expr, parser.tokens)) > 0 - + + multiple_paginations = any((expr(tok) for tok in parser.tokens)) + split = token.split_contents() as_index = None context_var = None From 17bf8606c32493d9c1fd15619c46b67292ddc7fe Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Wed, 16 Sep 2015 21:32:01 +0200 Subject: [PATCH 04/11] Bugfix release (Python 3) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 751d914..e6f9736 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = '1.0.7' +version = '1.0.7+bugfixes.2' LONG_DESCRIPTION = """ How to use django-pagination From db4477bc125bcceb8f722787b420af01ce1f68c2 Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Wed, 16 Sep 2015 21:32:24 +0200 Subject: [PATCH 05/11] Fix import for Django 1.8 --- pagination/templatetags/pagination_tags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pagination/templatetags/pagination_tags.py b/pagination/templatetags/pagination_tags.py index 4e03f80..64b5fd4 100644 --- a/pagination/templatetags/pagination_tags.py +++ b/pagination/templatetags/pagination_tags.py @@ -4,7 +4,7 @@ from sets import Set as set from django import template -from django.template import TOKEN_BLOCK +from django.template.base import TOKEN_BLOCK from django.http import Http404 from django.core.paginator import InvalidPage from django.conf import settings From 519e88fcdba0203074967edacad8413d26dd52aa Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Wed, 16 Sep 2015 21:32:32 +0200 Subject: [PATCH 06/11] Bugfix release (Django 1.8) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e6f9736..582e70e 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = '1.0.7+bugfixes.2' +version = '1.0.7+bugfixes.3' LONG_DESCRIPTION = """ How to use django-pagination From 8576ca0e1d70f70d31888d818931f193437d3980 Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Sun, 4 Oct 2015 16:44:07 +0200 Subject: [PATCH 07/11] gitignore build directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d7c2b72..7abee5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.pyc dist *.egg-info +build From 49421a10e9160277227204154a532f43b7556025 Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Sun, 4 Oct 2015 16:44:31 +0200 Subject: [PATCH 08/11] Refactor test script --- tests/runtests.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/runtests.py b/tests/runtests.py index 6fb4b93..18049e3 100644 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -2,15 +2,26 @@ sys.path.append('..') import os -# Make a backup of DJANGO_SETTINGS_MODULE environment variable to restore later. -backup = os.environ.get('DJANGO_SETTINGS_MODULE', '') -os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' -from django.test.simple import run_tests +import django +from django.conf import settings +from django.test.utils import get_runner -if __name__ == "__main__": - failures = run_tests(['pagination',], verbosity=9) + +def main(): + backup = os.environ.get('DJANGO_SETTINGS_MODULE', '') + os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' + + django.setup() + TestRunner = get_runner(settings) + test_runner = TestRunner() + + failures = test_runner.run_tests(['pagination',], verbosity=9) if failures: sys.exit(failures) + # Reset the DJANGO_SETTINGS_MODULE to what it was before running tests. os.environ['DJANGO_SETTINGS_MODULE'] = backup + +if __name__ == "__main__": + main() From f3d70804b34ae653c50ff4e44d1fb28c731f82ca Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Sun, 4 Oct 2015 16:44:43 +0200 Subject: [PATCH 09/11] paginate: do not fail if 'request' not in context The tests rely on this --- pagination/templatetags/pagination_tags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pagination/templatetags/pagination_tags.py b/pagination/templatetags/pagination_tags.py index 64b5fd4..7d570fd 100644 --- a/pagination/templatetags/pagination_tags.py +++ b/pagination/templatetags/pagination_tags.py @@ -224,7 +224,6 @@ def paginate(context, window=DEFAULT_WINDOW, hashtag=''): pages.extend(differenced) to_return = { 'MEDIA_URL': settings.MEDIA_URL, - 'request': context['request'], 'pages': pages, 'records': records, 'page_obj': page_obj, @@ -234,6 +233,7 @@ def paginate(context, window=DEFAULT_WINDOW, hashtag=''): 'page_suffix': page_suffix, } if 'request' in context: + to_return['request'] = context['request'] getvars = context['request'].GET.copy() if 'page%s' % page_suffix in getvars: del getvars['page%s' % page_suffix] From 77843e886d9c6301ee8bcbecbca6fb8bea88219e Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Sun, 4 Oct 2015 16:45:20 +0200 Subject: [PATCH 10/11] Convert tests to unittest from doctest The newer Django test runners don't execute doctests --- pagination/tests.py | 342 +++++++++++++++++++++++--------------------- 1 file changed, 176 insertions(+), 166 deletions(-) diff --git a/pagination/tests.py b/pagination/tests.py index f1cad49..7ae3b39 100644 --- a/pagination/tests.py +++ b/pagination/tests.py @@ -1,166 +1,176 @@ -""" ->>> from django.core.paginator import Paginator ->>> from pagination.templatetags.pagination_tags import paginate ->>> from django.template import Template, Context - ->>> p = Paginator(range(15), 2) ->>> pg = paginate({'paginator': p, 'page_obj': p.page(1)}) ->>> pg['pages'] -[1, 2, 3, 4, 5, 6, 7, 8] ->>> pg['records']['first'] -1 ->>> pg['records']['last'] -2 - ->>> p = Paginator(range(15), 2) ->>> pg = paginate({'paginator': p, 'page_obj': p.page(8)}) ->>> pg['pages'] -[1, 2, 3, 4, 5, 6, 7, 8] ->>> pg['records']['first'] -15 ->>> pg['records']['last'] -15 - ->>> p = Paginator(range(17), 2) ->>> paginate({'paginator': p, 'page_obj': p.page(1)})['pages'] -[1, 2, 3, 4, 5, 6, 7, 8, 9] - ->>> p = Paginator(range(19), 2) ->>> paginate({'paginator': p, 'page_obj': p.page(1)})['pages'] -[1, 2, 3, 4, None, 7, 8, 9, 10] - ->>> p = Paginator(range(21), 2) ->>> paginate({'paginator': p, 'page_obj': p.page(1)})['pages'] -[1, 2, 3, 4, None, 8, 9, 10, 11] - -# Testing orphans ->>> p = Paginator(range(5), 2, 1) ->>> paginate({'paginator': p, 'page_obj': p.page(1)})['pages'] -[1, 2] - ->>> p = Paginator(range(21), 2, 1) ->>> pg = paginate({'paginator': p, 'page_obj': p.page(1)}) ->>> pg['pages'] -[1, 2, 3, 4, None, 7, 8, 9, 10] ->>> pg['records']['first'] -1 ->>> pg['records']['last'] -2 - ->>> p = Paginator(range(21), 2, 1) ->>> pg = paginate({'paginator': p, 'page_obj': p.page(10)}) ->>> pg['pages'] -[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ->>> pg['records']['first'] -19 ->>> pg['records']['last'] -21 - ->>> p = Paginator(range(21), 2, 1) ->>> paginate({'paginator': p, 'page_obj': p.page(1)})['pages'] -[1, 2, 3, 4, None, 7, 8, 9, 10] - ->>> t = Template("{% load pagination_tags %}{% autopaginate var 2 %}{% paginate %}") - ->>> from django.http import HttpRequest as DjangoHttpRequest ->>> class HttpRequest(DjangoHttpRequest): -... page = lambda self, suffix: 1 - ->>> t.render(Context({'var': range(21), 'request': HttpRequest()})) -u'\\n\\n