diff --git a/django/views/generic/list.py b/django/views/generic/list.py index 2277ffd4d3..481929a987 100644 --- a/django/views/generic/list.py +++ b/django/views/generic/list.py @@ -5,6 +5,7 @@ from django.core.paginator import InvalidPage, Paginator from django.db.models.query import QuerySet from django.http import Http404 from django.utils import six +from django.utils.encoding import force_text from django.utils.translation import ugettext as _ from django.views.generic.base import ContextMixin, TemplateResponseMixin, View @@ -80,7 +81,7 @@ class MultipleObjectMixin(ContextMixin): except InvalidPage as e: raise Http404(_('Invalid page (%(page_number)s): %(message)s') % { 'page_number': page_number, - 'message': str(e) + 'message': force_text(e), }) def get_paginate_by(self, queryset): diff --git a/docs/releases/1.11.2.txt b/docs/releases/1.11.2.txt index ef235fa9ed..4dcfda7cc7 100644 --- a/docs/releases/1.11.2.txt +++ b/docs/releases/1.11.2.txt @@ -36,3 +36,6 @@ Bugfixes * Relaxed the validation added in Django 1.11 of the fields in the ``defaults`` argument of ``QuerySet.get_or_create()`` and ``update_or_create()`` to reallow settable model properties (:ticket:`28222`). + +* Fixed ``MultipleObjectMixin.paginate_queryset()`` crash on Python 2 if the + ``InvalidPage`` message contains non-ASCII (:ticket:`28204`). diff --git a/tests/generic_views/test_list.py b/tests/generic_views/test_list.py index 5a22abd33b..37408e8662 100644 --- a/tests/generic_views/test_list.py +++ b/tests/generic_views/test_list.py @@ -5,6 +5,7 @@ import datetime from django.core.exceptions import ImproperlyConfigured from django.test import TestCase, override_settings +from django.utils import translation from django.utils.encoding import force_str from django.views.generic.base import View @@ -103,6 +104,13 @@ class ListViewTests(TestCase): res = self.client.get('/list/authors/paginated/42/') self.assertEqual(res.status_code, 404) + def test_paginated_page_out_of_range_non_ascii_message(self): + msg = 'Ung\xfcltige Seite (42): Diese Seite enth\xe4lt keine Ergebnisse' + with translation.override('de'): + res = self.client.get('/list/authors/paginated/42/') + self.assertEqual(res.status_code, 404) + self.assertEqual(res.context['exception'], msg) + def test_paginated_invalid_page(self): self._make_authors(100) res = self.client.get('/list/authors/paginated/?page=frog')