Skip to content

Commit c2a91f5

Browse files
authored
Merge pull request #150 from StyXman/merge_support_views
Merge support views. We could probably fix 5174f68 in another way, in particular, returning a set directly.
2 parents 6673ef2 + 84b8f1f commit c2a91f5

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

Diff for: rest_framework_docs/api_endpoint.py

+22-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
import json
22
import inspect
3+
34
from django.contrib.admindocs.views import simplify_regex
45
from django.utils.encoding import force_str
6+
7+
from rest_framework.viewsets import ModelViewSet
58
from rest_framework.serializers import BaseSerializer
69

10+
VIEWSET_METHODS = {
11+
'List': ['get', 'post'],
12+
'Instance': ['get', 'put', 'patch', 'delete'],
13+
}
14+
715

816
class ApiEndpoint(object):
917

@@ -31,8 +39,14 @@ def __get_path__(self, parent_regex):
3139
return "/{0}{1}".format(self.name_parent, simplify_regex(self.pattern.regex.pattern))
3240
return simplify_regex(self.pattern.regex.pattern)
3341

34-
def __get_allowed_methods__(self):
42+
def is_method_allowed(self, callback_cls, method_name):
43+
has_attr = hasattr(callback_cls, method_name)
44+
viewset_method = (issubclass(callback_cls, ModelViewSet) and
45+
method_name in VIEWSET_METHODS.get(self.callback.suffix, []))
46+
47+
return has_attr or viewset_method
3548

49+
def __get_allowed_methods__(self):
3650
viewset_methods = []
3751
if self.drf_router:
3852
for prefix, viewset, basename in self.drf_router.registry:
@@ -57,14 +71,18 @@ def __get_allowed_methods__(self):
5771
)
5872
if self.pattern.regex.pattern == regex:
5973
funcs, viewset_methods = zip(
60-
*[(mapping[m], m.upper()) for m in self.callback.cls.http_method_names if m in mapping]
74+
*[(mapping[m], m.upper())
75+
for m in self.callback.cls.http_method_names
76+
if m in mapping]
6177
)
6278
viewset_methods = list(viewset_methods)
6379
if len(set(funcs)) == 1:
6480
self.docstring = inspect.getdoc(getattr(self.callback.cls, funcs[0]))
6581

66-
view_methods = [force_str(m).upper() for m in self.callback.cls.http_method_names if hasattr(self.callback.cls, m)]
67-
return viewset_methods + view_methods
82+
view_methods = [force_str(m).upper()
83+
for m in self.callback.cls.http_method_names
84+
if self.is_method_allowed(self.callback.cls, m)]
85+
return sorted(viewset_methods + view_methods)
6886

6987
def __get_docstring__(self):
7088
return inspect.getdoc(self.callback)

Diff for: tests/tests.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def test_settings_module(self):
2121

2222
def test_index_view_with_endpoints(self):
2323
"""
24-
Should load the drf focs view with all the endpoints.
24+
Should load the drf docs view with all the endpoints.
2525
NOTE: Views that do **not** inherit from DRF's "APIView" are not included.
2626
"""
2727
response = self.client.get(reverse('drfdocs'))
@@ -31,15 +31,15 @@ def test_index_view_with_endpoints(self):
3131

3232
# Test the login view
3333
self.assertEqual(response.context["endpoints"][0].name_parent, "accounts")
34-
self.assertEqual(response.context["endpoints"][0].allowed_methods, ['POST', 'OPTIONS'])
34+
self.assertEqual(set(response.context["endpoints"][0].allowed_methods), set(['OPTIONS', 'POST']))
3535
self.assertEqual(response.context["endpoints"][0].path, "/accounts/login/")
3636
self.assertEqual(response.context["endpoints"][0].docstring, "A view that allows users to login providing their username and password.")
3737
self.assertEqual(len(response.context["endpoints"][0].fields), 2)
3838
self.assertEqual(response.context["endpoints"][0].fields[0]["type"], "CharField")
3939
self.assertTrue(response.context["endpoints"][0].fields[0]["required"])
4040

4141
self.assertEqual(response.context["endpoints"][1].name_parent, "accounts")
42-
self.assertEqual(response.context["endpoints"][1].allowed_methods, ['POST', 'OPTIONS'])
42+
self.assertEqual(set(response.context["endpoints"][1].allowed_methods), set(['POST', 'OPTIONS']))
4343
self.assertEqual(response.context["endpoints"][1].path, "/accounts/login2/")
4444
self.assertEqual(response.context["endpoints"][1].docstring, "A view that allows users to login providing their username and password. Without serializer_class")
4545
self.assertEqual(len(response.context["endpoints"][1].fields), 2)
@@ -77,7 +77,7 @@ def test_model_viewset(self):
7777
self.assertEqual(response.context['endpoints'][6].fields[2]['to_many_relation'], True)
7878
self.assertEqual(response.context["endpoints"][11].path, '/organisation-model-viewsets/')
7979
self.assertEqual(response.context["endpoints"][12].path, '/organisation-model-viewsets/<pk>/')
80-
self.assertEqual(response.context["endpoints"][11].allowed_methods, ['GET', 'POST', 'OPTIONS'])
81-
self.assertEqual(response.context["endpoints"][12].allowed_methods, ['GET', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'])
82-
self.assertEqual(response.context["endpoints"][13].allowed_methods, ['POST', 'OPTIONS'])
80+
self.assertEqual(set(response.context["endpoints"][11].allowed_methods), set(['GET', 'POST', 'OPTIONS']))
81+
self.assertEqual(set(response.context["endpoints"][12].allowed_methods), set(['GET', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']))
82+
self.assertEqual(set(response.context["endpoints"][13].allowed_methods), set(['POST', 'OPTIONS']))
8383
self.assertEqual(response.context["endpoints"][13].docstring, 'This is a test.')

0 commit comments

Comments
 (0)