Preserve existing query params in PaginatorMixin

Previously, generation of next/previous links would discard any existing
query parameters. This commit introduces a dependency on URLObject, which
is used to intelligently parse and modify URLs to ensure existing params
are preserved.

Addresses issues #107
This commit is contained in:
Jamie Matthews 2012-01-05 14:07:31 +00:00
parent b745d0c2f4
commit 18535c7a38
4 changed files with 17 additions and 2 deletions

View File

@ -7,6 +7,7 @@ from django.contrib.auth.models import AnonymousUser
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.db.models.fields.related import ForeignKey from django.db.models.fields.related import ForeignKey
from django.http import HttpResponse from django.http import HttpResponse
from urlobject import URLObject
from djangorestframework import status from djangorestframework import status
from djangorestframework.renderers import BaseRenderer from djangorestframework.renderers import BaseRenderer
@ -659,11 +660,12 @@ class PaginatorMixin(object):
def url_with_page_number(self, page_number): def url_with_page_number(self, page_number):
""" Constructs a url used for getting the next/previous urls """ """ Constructs a url used for getting the next/previous urls """
url = "%s?page=%d" % (self.request.path, page_number) url = URLObject.parse(self.request.get_full_path())
url = url.add_query_param('page', page_number)
limit = self.get_limit() limit = self.get_limit()
if limit != self.limit: if limit != self.limit:
url = "%s&limit=%d" % (url, limit) url = url.add_query_param('limit', limit)
return url return url

View File

@ -237,3 +237,14 @@ class TestPagination(TestCase):
response = MockPaginatorView.as_view()(request) response = MockPaginatorView.as_view()(request)
content = json.loads(response.content) content = json.loads(response.content)
self.assertEqual(response.status_code, status.NOT_FOUND) self.assertEqual(response.status_code, status.NOT_FOUND)
def test_existing_query_parameters_are_preserved(self):
""" Tests that existing query parameters are preserved when
generating next/previous page links """
request = self.req.get('/paginator/?foo=bar&another=something')
response = MockPaginatorView.as_view()(request)
content = json.loads(response.content)
self.assertEqual(response.status_code, status.OK)
self.assertTrue('foo=bar' in content['next'])
self.assertTrue('another=something' in content['next'])
self.assertTrue('page=2' in content['next'])

View File

@ -3,3 +3,4 @@
Django>=1.2 Django>=1.2
coverage>=3.4 coverage>=3.4
URLObject>=0.6.0

View File

@ -26,6 +26,7 @@ setup(
package_dir={'djangorestframework': 'djangorestframework'}, package_dir={'djangorestframework': 'djangorestframework'},
package_data = {'djangorestframework': ['templates/*', 'static/*']}, package_data = {'djangorestframework': ['templates/*', 'static/*']},
test_suite = 'djangorestframework.runtests.runcoverage.main', test_suite = 'djangorestframework.runtests.runcoverage.main',
install_requires=['URLObject>=0.6.0'],
classifiers = [ classifiers = [
'Development Status :: 4 - Beta', 'Development Status :: 4 - Beta',
'Environment :: Web Environment', 'Environment :: Web Environment',