Repository: encode/django-rest-framework

Issue:
Checking for request.version raises AttributeError with BrowsableAPIRenderer
I've encountered the following exception when using the Browsable API in conjunction with the new namespace versioning and HyperlinkedModelSerializers:

``` python
AttributeError: 'WSGIRequest' object has no attribute 'version'
```

I've implemented `get_serializer_class()` as specified in the documentation:

``` python
def get_serializer_class(self):
    if self.request.version == 'v1':
        return AccountSerializerVersion1
    return AccountSerializer
```

I'm also using drf-nested-routers, and this is occurring on endpoints like /api/v1/car/1/tires/ where the Tire model has a ForeignKey to Car.

This only happens on the Browsable API; I can perform a GET request to the same endpoint using the JSONRenderer without exceptions.

Checking for request.version raises AttributeError with BrowsableAPIRenderer
I've encountered the following exception when using the Browsable API in conjunction with the new namespace versioning and HyperlinkedModelSerializers:

``` python
AttributeError: 'WSGIRequest' object has no attribute 'version'
```

I've implemented `get_serializer_class()` as specified in the documentation:

``` python
def get_serializer_class(self):
    if self.request.version == 'v1':
        return AccountSerializerVersion1
    return AccountSerializer
```

I'm also using drf-nested-routers, and this is occurring on endpoints like /api/v1/car/1/tires/ where the Tire model has a ForeignKey to Car.

This only happens on the Browsable API; I can perform a GET request to the same endpoint using the JSONRenderer without exceptions.



Discussion:

Resolving patch:
diff --git a/rest_framework/request.py b/rest_framework/request.py
--- a/rest_framework/request.py
+++ b/rest_framework/request.py
@@ -107,6 +107,8 @@ def clone_request(request, method):
         ret.accepted_renderer = request.accepted_renderer
     if hasattr(request, 'accepted_media_type'):
         ret.accepted_media_type = request.accepted_media_type
+    if hasattr(request, 'version'):
+        ret.version = request.version
     return ret
 
 


Test patch:
diff --git a/tests/browsable_api/auth_urls.py b/tests/browsable_api/auth_urls.py
--- a/tests/browsable_api/auth_urls.py
+++ b/tests/browsable_api/auth_urls.py
@@ -3,6 +3,7 @@
 
 from .views import MockView
 
+
 urlpatterns = patterns(
     '',
     (r'^$', MockView.as_view()),
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -1,6 +1,7 @@
 from __future__ import unicode_literals
 from rest_framework import exceptions, serializers, status, views
 from rest_framework.request import Request
+from rest_framework.renderers import BrowsableAPIRenderer
 from rest_framework.test import APIRequestFactory
 
 request = Request(APIRequestFactory().options('/'))
@@ -168,3 +169,17 @@ def get_object(self):
         response = view(request=request)
         assert response.status_code == status.HTTP_200_OK
         assert list(response.data['actions'].keys()) == ['POST']
+
+    def test_bug_2455_clone_request(self):
+        class ExampleView(views.APIView):
+            renderer_classes = (BrowsableAPIRenderer,)
+
+            def post(self, request):
+                pass
+
+            def get_serializer(self):
+                assert hasattr(self.request, 'version')
+                return serializers.Serializer()
+
+        view = ExampleView.as_view()
+        view(request=request)