From ec8e7f27e7250b7fb93fbf3ee01e03b94643311b Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 19 May 2015 15:49:37 +0100 Subject: [PATCH] Fixes for format preservation --- rest_framework/renderers.py | 2 +- rest_framework/reverse.py | 27 +++++++++++++++++++++++---- rest_framework/utils/breadcrumbs.py | 7 ++++--- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 93400c0bb..bfc8bd5cb 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -586,7 +586,7 @@ class BrowsableAPIRenderer(BaseRenderer): return view.get_view_description(html=True) def get_breadcrumbs(self, request): - return get_breadcrumbs(request.path) + return get_breadcrumbs(request.path, request) def get_context(self, data, accepted_media_type, renderer_context): """ diff --git a/rest_framework/reverse.py b/rest_framework/reverse.py index 7235ac5d4..7cb910274 100644 --- a/rest_framework/reverse.py +++ b/rest_framework/reverse.py @@ -10,6 +10,27 @@ from rest_framework.settings import api_settings from rest_framework.utils.urls import replace_query_param +def preserve_builtin_query_params(url, request=None): + """ + Given an incoming request, and an outgoing URL representation, + append the value of any built-in query parameters. + """ + if request is None: + return url + + overrides = [ + api_settings.URL_FORMAT_OVERRIDE, + api_settings.URL_ACCEPT_OVERRIDE + ] + + for param in overrides: + if param and (param in request.GET): + value = request.GET[param] + url = replace_query_param(url, param, value) + + return url + + def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra): """ If versioning is being used then we pass any `reverse` calls through @@ -27,10 +48,8 @@ def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra else: url = _reverse(viewname, args, kwargs, request, format, **extra) - FORMAT_OVERRIDE = api_settings.URL_FORMAT_OVERRIDE - if FORMAT_OVERRIDE and (FORMAT_OVERRIDE in request.query_params): - return replace_query_param(url, FORMAT_OVERRIDE, request.query_params[FORMAT_OVERRIDE]) - return url + return preserve_builtin_query_params(url, request) + def _reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra): """ diff --git a/rest_framework/utils/breadcrumbs.py b/rest_framework/utils/breadcrumbs.py index e6690d170..b2a74376e 100644 --- a/rest_framework/utils/breadcrumbs.py +++ b/rest_framework/utils/breadcrumbs.py @@ -2,12 +2,12 @@ from __future__ import unicode_literals from django.core.urlresolvers import resolve, get_script_prefix -def get_breadcrumbs(url): +def get_breadcrumbs(url, request=None): """ Given a url returns a list of breadcrumbs, which are each a tuple of (name, url). """ - + from rest_framework.reverse import preserve_builtin_query_params from rest_framework.settings import api_settings from rest_framework.views import APIView @@ -33,7 +33,8 @@ def get_breadcrumbs(url): if not seen or seen[-1] != view: suffix = getattr(view, 'suffix', None) name = view_name_func(cls, suffix) - breadcrumbs_list.insert(0, (name, prefix + url)) + insert_url = preserve_builtin_query_params(prefix + url, request) + breadcrumbs_list.insert(0, (name, insert_url)) seen.append(view) if url == '':