From 1f72fd42bcefcf5a2763f9516c06c0a91364a260 Mon Sep 17 00:00:00 2001 From: NK Date: Mon, 7 Apr 2014 17:17:34 +0300 Subject: [PATCH 1/4] The OPTIONS method creates a cloned-request to simulate PUT/POST methods. But the implementation did not propagate the cloned-request to the View. This caused views that change the serializer per the http-method to return the incorrect serializer. --- rest_framework/generics.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 7bac510f7..346d74032 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -371,10 +371,11 @@ class GenericAPIView(views.APIView): if method not in self.allowed_methods: continue - cloned_request = clone_request(request, method) + original_request = clone_request(request, request.method) + self.request = clone_request(request, method) try: # Test global permissions - self.check_permissions(cloned_request) + self.check_permissions(self.request) # Test object permissions if method == 'PUT': try: @@ -392,6 +393,7 @@ class GenericAPIView(views.APIView): # appropriate metadata about the fields that should be supplied. serializer = self.get_serializer() actions[method] = serializer.metadata() + self.request = original_request if actions: ret['actions'] = actions From 63a6d6b778d247c6d063a9b87687945b60d04fd1 Mon Sep 17 00:00:00 2001 From: NK Date: Tue, 8 Apr 2014 12:39:59 +0300 Subject: [PATCH 2/4] Added unit-test that checks OPTIONS response for dynamic serializers --- rest_framework/runtests/runtests.py | 2 +- rest_framework/tests/test_generics.py | 28 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/rest_framework/runtests/runtests.py b/rest_framework/runtests/runtests.py index 2daaae4ee..cd0defec8 100755 --- a/rest_framework/runtests/runtests.py +++ b/rest_framework/runtests/runtests.py @@ -43,7 +43,7 @@ def main(): test_module_name = 'rest_framework.tests' if django.VERSION[0] == 1 and django.VERSION[1] < 6: test_module_name = 'tests' - + print test_module_name + test_case failures = test_runner.run_tests([test_module_name + test_case]) sys.exit(failures) diff --git a/rest_framework/tests/test_generics.py b/rest_framework/tests/test_generics.py index 996bd5b0e..5b3c00beb 100644 --- a/rest_framework/tests/test_generics.py +++ b/rest_framework/tests/test_generics.py @@ -607,3 +607,31 @@ class TestFilterBackendAppliedToViews(TestCase): response = view(request).render() self.assertContains(response, 'field_b') self.assertNotContains(response, 'field_a') + + def test_options_with_dynamic_serializer(self): + """ + Ensure that OPTIONS returns correct POST json schema: DynamicSerializer with single field 'field_b' + """ + request = factory.options('/') + view = DynamicSerializerView.as_view() + with self.assertNumQueries(0): + response = view(request).render() + expected = { + u'name': u'Dynamic Serializer', + u'description': u'', + u'renders': [u'text/html', u'application/json'], + u'parses': [u'application/json', u'application/x-www-form-urlencoded', u'multipart/form-data'], + u'actions': { + u'POST': { + u'field_b': { + u'type': u'string', + u'required': True, + u'read_only': False, + u'label': u'field b', + u'max_length': 100 + } + } + } + } + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data, expected) \ No newline at end of file From 09c2d7fe3886f9bf3f2d5afa32e12ca66cd1140e Mon Sep 17 00:00:00 2001 From: NadavK Date: Tue, 8 Apr 2014 12:46:01 +0300 Subject: [PATCH 3/4] Update runtests.py --- rest_framework/runtests/runtests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/rest_framework/runtests/runtests.py b/rest_framework/runtests/runtests.py index cd0defec8..55eabfaa8 100755 --- a/rest_framework/runtests/runtests.py +++ b/rest_framework/runtests/runtests.py @@ -43,7 +43,6 @@ def main(): test_module_name = 'rest_framework.tests' if django.VERSION[0] == 1 and django.VERSION[1] < 6: test_module_name = 'tests' - print test_module_name + test_case failures = test_runner.run_tests([test_module_name + test_case]) sys.exit(failures) From 8843193ac627b1005d4649b1747eccbde54edd5e Mon Sep 17 00:00:00 2001 From: NK Date: Tue, 8 Apr 2014 14:09:20 +0300 Subject: [PATCH 4/4] Removed unicode (u) prefix --- rest_framework/tests/test_generics.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rest_framework/tests/test_generics.py b/rest_framework/tests/test_generics.py index 5b3c00beb..07c8b983d 100644 --- a/rest_framework/tests/test_generics.py +++ b/rest_framework/tests/test_generics.py @@ -617,18 +617,18 @@ class TestFilterBackendAppliedToViews(TestCase): with self.assertNumQueries(0): response = view(request).render() expected = { - u'name': u'Dynamic Serializer', - u'description': u'', - u'renders': [u'text/html', u'application/json'], - u'parses': [u'application/json', u'application/x-www-form-urlencoded', u'multipart/form-data'], - u'actions': { - u'POST': { - u'field_b': { - u'type': u'string', - u'required': True, - u'read_only': False, - u'label': u'field b', - u'max_length': 100 + 'name': 'Dynamic Serializer', + 'description': '', + 'renders': ['text/html', 'application/json'], + 'parses': ['application/json', 'application/x-www-form-urlencoded', 'multipart/form-data'], + 'actions': { + 'POST': { + 'field_b': { + 'type': 'string', + 'required': True, + 'read_only': False, + 'label': 'field b', + 'max_length': 100 } } }