From 225c47beede0bb0dff5a64cca0e14477537491e3 Mon Sep 17 00:00:00 2001 From: Maxence Date: Thu, 21 Jan 2016 09:55:37 +0100 Subject: [PATCH 1/4] Support Model View Sets --- rest_framework_docs/api_endpoint.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/rest_framework_docs/api_endpoint.py b/rest_framework_docs/api_endpoint.py index f37155c..d991d2b 100644 --- a/rest_framework_docs/api_endpoint.py +++ b/rest_framework_docs/api_endpoint.py @@ -2,6 +2,12 @@ import inspect from django.contrib.admindocs.views import simplify_regex from django.utils.encoding import force_str +from rest_framework.viewsets import ModelViewSet + +VIEWSET_METHODS = { + 'List': ['get', 'post'], + 'Instance': ['get', 'put', 'patch', 'delete'], +} class ApiEndpoint(object): @@ -25,8 +31,14 @@ def __get_path__(self, parent_pattern): return "/{0}{1}".format(self.name_parent, simplify_regex(self.pattern.regex.pattern)) return simplify_regex(self.pattern.regex.pattern) + def is_method_allowed(self, method_name, callback_cls): + return hasattr(callback_cls, method_name) or ( + issubclass(callback_cls, ModelViewSet) and method_name in VIEWSET_METHODS.get(self.callback.suffix, []) + ) + def __get_allowed_methods__(self): - return [force_str(m).upper() for m in self.callback.cls.http_method_names if hasattr(self.callback.cls, m)] + callback_cls = self.callback.cls + return sorted([force_str(name).upper() for name in callback_cls.http_method_names if self.is_method_allowed(name, callback_cls)]) def __get_docstring__(self): return inspect.getdoc(self.callback) From f44ccbae43a9b1614b0c61f164175ae2fa6748eb Mon Sep 17 00:00:00 2001 From: Brobin Date: Fri, 8 Apr 2016 14:50:26 -0500 Subject: [PATCH 2/4] fix broken test by sorting both lists --- tests/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests.py b/tests/tests.py index afb58d0..c1978ec 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -31,7 +31,7 @@ def test_index_view_with_endpoints(self): # Test the login view self.assertEqual(response.context["endpoints"][0].name_parent, "accounts") - self.assertEqual(response.context["endpoints"][0].allowed_methods, ['POST', 'OPTIONS']) + self.assertEqual(sorted(response.context["endpoints"][0].allowed_methods), sorted(['OPTIONS', 'POST'])) self.assertEqual(response.context["endpoints"][0].path, "/accounts/login/") self.assertEqual(response.context["endpoints"][0].docstring, "A view that allows users to login providing their username and password.") self.assertEqual(len(response.context["endpoints"][0].fields), 2) From 5174f68bee65cfe8790f8d14b8423ab9603ea8a8 Mon Sep 17 00:00:00 2001 From: Marcos Dione Date: Wed, 25 Jan 2017 18:48:49 +0100 Subject: [PATCH 3/4] Make sure methods returned by allowed_methods can be in any order and count. We might need to make sure that the returned value is a set. --- tests/tests.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/tests.py b/tests/tests.py index c49499a..c394147 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -31,7 +31,7 @@ def test_index_view_with_endpoints(self): # Test the login view self.assertEqual(response.context["endpoints"][0].name_parent, "accounts") - self.assertEqual(sorted(response.context["endpoints"][0].allowed_methods), sorted(['OPTIONS', 'POST'])) + self.assertEqual(set(response.context["endpoints"][0].allowed_methods), set(['OPTIONS', 'POST'])) self.assertEqual(response.context["endpoints"][0].path, "/accounts/login/") self.assertEqual(response.context["endpoints"][0].docstring, "A view that allows users to login providing their username and password.") self.assertEqual(len(response.context["endpoints"][0].fields), 2) @@ -39,7 +39,7 @@ def test_index_view_with_endpoints(self): self.assertTrue(response.context["endpoints"][0].fields[0]["required"]) self.assertEqual(response.context["endpoints"][1].name_parent, "accounts") - self.assertEqual(response.context["endpoints"][1].allowed_methods, ['POST', 'OPTIONS']) + self.assertEqual(set(response.context["endpoints"][1].allowed_methods), set(['POST', 'OPTIONS'])) self.assertEqual(response.context["endpoints"][1].path, "/accounts/login2/") self.assertEqual(response.context["endpoints"][1].docstring, "A view that allows users to login providing their username and password. Without serializer_class") self.assertEqual(len(response.context["endpoints"][1].fields), 2) @@ -77,7 +77,7 @@ def test_model_viewset(self): self.assertEqual(response.context['endpoints'][6].fields[2]['to_many_relation'], True) self.assertEqual(response.context["endpoints"][11].path, '/organisation-model-viewsets/') self.assertEqual(response.context["endpoints"][12].path, '/organisation-model-viewsets//') - self.assertEqual(response.context["endpoints"][11].allowed_methods, ['GET', 'POST', 'OPTIONS']) - self.assertEqual(response.context["endpoints"][12].allowed_methods, ['GET', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']) - self.assertEqual(response.context["endpoints"][13].allowed_methods, ['POST', 'OPTIONS']) + self.assertEqual(set(response.context["endpoints"][11].allowed_methods), set(['GET', 'POST', 'OPTIONS'])) + self.assertEqual(set(response.context["endpoints"][12].allowed_methods), set(['GET', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'])) + self.assertEqual(set(response.context["endpoints"][13].allowed_methods), set(['POST', 'OPTIONS'])) self.assertEqual(response.context["endpoints"][13].docstring, 'This is a test.') From 84b8f1f45fb12281c53f1c35dbd86775b31c04a3 Mon Sep 17 00:00:00 2001 From: Marcos Dione Date: Wed, 25 Jan 2017 18:49:04 +0100 Subject: [PATCH 4/4] Typo. --- tests/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests.py b/tests/tests.py index c394147..f94736c 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -21,7 +21,7 @@ def test_settings_module(self): def test_index_view_with_endpoints(self): """ - Should load the drf focs view with all the endpoints. + Should load the drf docs view with all the endpoints. NOTE: Views that do **not** inherit from DRF's "APIView" are not included. """ response = self.client.get(reverse('drfdocs'))