diff --git a/drf_spectacular/generators.py b/drf_spectacular/generators.py index faea62f7..33f5d533 100644 --- a/drf_spectacular/generators.py +++ b/drf_spectacular/generators.py @@ -39,6 +39,12 @@ def get_api_endpoints(self, patterns=None, prefix=''): else: return api_endpoints + def get_path_from_regex(self, path_regex): + path = super().get_path_from_regex(path_regex) + # bugfix oversight in DRF regex stripping + path = path.replace('\\.', '.') + return path + def _get_api_endpoints(self, patterns, prefix): """ Return a list of all available API endpoints by inspecting the URL conf. diff --git a/tests/test_regressions.py b/tests/test_regressions.py index a9ab152e..2fa83c28 100644 --- a/tests/test_regressions.py +++ b/tests/test_regressions.py @@ -2133,3 +2133,22 @@ class XViewset(viewsets.ModelViewSet): assert schema['components']['schemas']['X']['properties']['field'] == { 'type': 'integer', 'default': 3 } + + +def test_literal_dot_in_regex_path(no_warnings): + @extend_schema( + responses=OpenApiTypes.ANY, + parameters=[ + OpenApiParameter('filename', str, OpenApiParameter.PATH), + OpenApiParameter('ext', str, OpenApiParameter.PATH) + ] + ) + @api_view(['GET']) + def view_func(request, format=None): + pass # pragma: no cover + + urlpatterns = [ + re_path('^file/(?P.*)\\.(?P\\w+)$', view_func) + ] + schema = generate_schema(None, patterns=urlpatterns) + assert '/file/{filename}.{ext}' in schema['paths']