Skip to content

Commit 637a263

Browse files
dongfangtianyucarltongibson
authored andcommitted
OpenAPI: Ensure operations have unique operationIds.
1 parent 2964602 commit 637a263

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

rest_framework/schemas/openapi.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,11 @@ def _get_operation_id(self, path, method):
104104
# Avoid cyclic imports
105105
from rest_framework.generics import GenericAPIView
106106

107+
method_name = getattr(self.view, 'action', method.lower())
107108
if is_list_view(path, method, self.view):
108109
action = 'List'
110+
elif method_name not in self.method_mapping:
111+
action = method_name
109112
else:
110113
action = self.method_mapping[method.lower()]
111114

tests/schemas/test_openapi.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from django.conf.urls import url
33
from django.test import RequestFactory, TestCase, override_settings
44

5-
from rest_framework import filters, generics, pagination, serializers
5+
from rest_framework import filters, generics, pagination, routers, serializers
66
from rest_framework.compat import uritemplate
77
from rest_framework.request import Request
88
from rest_framework.schemas.openapi import AutoSchema, SchemaGenerator
@@ -160,6 +160,21 @@ class View(generics.GenericAPIView):
160160
assert list(schema['properties']['nested']['properties'].keys()) == ['number']
161161
assert schema['properties']['nested']['required'] == ['number']
162162

163+
def test_repeat_operation_ids(self):
164+
router = routers.SimpleRouter()
165+
router.register('account', views.ExampleGenericViewSet, basename="account")
166+
urlpatterns = router.urls
167+
168+
generator = SchemaGenerator(patterns=urlpatterns)
169+
170+
request = create_request('/')
171+
schema = generator.get_schema(request=request)
172+
schema_str = str(schema)
173+
print(schema_str)
174+
assert schema_str.count("operationId") == 2
175+
assert schema_str.count("newExample") == 1
176+
assert schema_str.count("oldExample") == 1
177+
163178

164179
@pytest.mark.skipif(uritemplate is None, reason='uritemplate not installed.')
165180
@override_settings(REST_FRAMEWORK={'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.openapi.AutoSchema'})

tests/schemas/views.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from rest_framework import permissions, serializers
2+
from rest_framework.decorators import action
23
from rest_framework.response import Response
34
from rest_framework.views import APIView
45
from rest_framework.viewsets import GenericViewSet
@@ -34,3 +35,11 @@ def get(self, *args, **kwargs):
3435

3536
serializer = self.get_serializer(data=now.date(), datetime=now)
3637
return Response(serializer.data)
38+
39+
@action(detail=False)
40+
def new(self, *args, **kwargs):
41+
pass
42+
43+
@action(detail=False)
44+
def old(self, *args, **kwargs):
45+
pass

0 commit comments

Comments
 (0)