From 5ca4fc48cbad3c1220bc9f3997b07a99f14a9845 Mon Sep 17 00:00:00 2001 From: Jekel <> Date: Sat, 16 Sep 2023 23:01:48 +0300 Subject: [PATCH] Use correctly allowed http methods for schema generation --- drf_spectacular/generators.py | 14 +++++++++++++- tests/test_regressions.py | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/drf_spectacular/generators.py b/drf_spectacular/generators.py index ad71d35f..16bbad64 100644 --- a/drf_spectacular/generators.py +++ b/drf_spectacular/generators.py @@ -75,7 +75,19 @@ def _get_api_endpoints(self, patterns, prefix): return api_endpoints def get_allowed_methods(self, callback): - methods = super().get_allowed_methods(callback) + if hasattr(callback, 'actions'): + actions = set(callback.actions) + http_method_names = set(callback.cls.http_method_names) + methods = [method.upper() for method in actions & http_method_names] + else: + # pass to constructor allowed method names to get valid ones + kwargs = {} + http_method_names = callback.initkwargs.get('http_method_names', []) + if http_method_names: + kwargs['http_method_names'] = http_method_names + + methods = callback.cls(**kwargs).allowed_methods + return [ method for method in methods if method not in ('OPTIONS', 'HEAD', 'TRACE', 'CONNECT') diff --git a/tests/test_regressions.py b/tests/test_regressions.py index 94440c6e..2da2105b 100644 --- a/tests/test_regressions.py +++ b/tests/test_regressions.py @@ -956,6 +956,27 @@ def get(self, request): assert '#/components/schemas/X' in get_response_schema(operation)['$ref'] +def test_schema_contains_only_allowed_methods(no_warnings): + class XSerializer(serializers.Serializer): + integer = serializers.IntegerField() + + class X(models.Model): + integer = models.IntegerField() + + class XAPIView(generics.ListCreateAPIView): + model = X + serializer_class = XSerializer + + urlpatterns = [ + path('api/x/', XAPIView.as_view()), + path('api/x1/', XAPIView.as_view(http_method_names=['post'])), + ] + schema = generate_schema(None, patterns=urlpatterns) + assert sorted(schema['paths']['/api/x/'].keys()) == sorted(['get', 'post']) + assert list(schema['paths']['/api/x1/'].keys()) == ['post'] + assert 'X' in schema['components']['schemas'] + + def test_auto_schema_and_extend_parameters(no_warnings): class CustomAutoSchema(AutoSchema): def get_override_parameters(self):