Repository: encode/django-rest-framework

Issue:
OpenAPI Schema: rendering to json fails for timedelta
## Checklist

- [x] I have verified that that issue exists against the `master` branch of Django REST framework.
- [x] I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
- [x] This is not a usage question. (Those should be directed to the [discussion group](https://groups.google.com/forum/#!forum/django-rest-framework) instead.)
- [x] This cannot be dealt with as a third party library. (We prefer new functionality to be [in the form of third party libraries](https://www.django-rest-framework.org/community/third-party-packages/#about-third-party-packages) where possible.)
- [x] I have reduced the issue to the simplest possible case.
- [x] I have included a failing test as a pull request. (If you are unable to do so we can still accept the issue.)

## Steps to reproduce

- Define a Serializer with a DurationField, use a timedelta as `default`,  `min_value` or `max_value`. For example:

```
class ExampleSerializer(serializers.Serializer):
    duration = serializers.DurationField(default=timedelta())
```

- Create an APIView using this Serializer

OpenAPI schema generation, rendered as json, will fail.  

## Expected behavior

json rendering should not raise an error.

## Actual behavior

 `TypeError: Object of type 'timedelta' is not JSON serializable` is raised



Discussion:

Resolving patch:
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py
--- a/rest_framework/renderers.py
+++ b/rest_framework/renderers.py
@@ -1063,7 +1063,8 @@ def ignore_aliases(self, data):
 class JSONOpenAPIRenderer(BaseRenderer):
     media_type = 'application/vnd.oai.openapi+json'
     charset = None
+    encoder_class = encoders.JSONEncoder
     format = 'openapi-json'
 
     def render(self, data, media_type=None, renderer_context=None):
-        return json.dumps(data, indent=2).encode('utf-8')
+        return json.dumps(data, cls=self.encoder_class, indent=2).encode('utf-8')


Test patch:
diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py
--- a/tests/schemas/test_openapi.py
+++ b/tests/schemas/test_openapi.py
@@ -11,7 +11,8 @@
 from rest_framework.compat import uritemplate
 from rest_framework.parsers import JSONParser, MultiPartParser
 from rest_framework.renderers import (
-    BaseRenderer, BrowsableAPIRenderer, JSONRenderer, OpenAPIRenderer
+    BaseRenderer, BrowsableAPIRenderer, JSONOpenAPIRenderer, JSONRenderer,
+    OpenAPIRenderer
 )
 from rest_framework.request import Request
 from rest_framework.schemas.openapi import AutoSchema, SchemaGenerator
@@ -992,6 +993,19 @@ def test_schema_construction(self):
         assert 'openapi' in schema
         assert 'paths' in schema
 
+    def test_schema_rendering_to_json(self):
+        patterns = [
+            path('example/', views.ExampleGenericAPIView.as_view()),
+        ]
+        generator = SchemaGenerator(patterns=patterns)
+
+        request = create_request('/')
+        schema = generator.get_schema(request=request)
+        ret = JSONOpenAPIRenderer().render(schema)
+
+        assert b'"openapi": "' in ret
+        assert b'"default": "0.0"' in ret
+
     def test_schema_with_no_paths(self):
         patterns = []
         generator = SchemaGenerator(patterns=patterns)
diff --git a/tests/schemas/views.py b/tests/schemas/views.py
--- a/tests/schemas/views.py
+++ b/tests/schemas/views.py
@@ -1,4 +1,5 @@
 import uuid
+from datetime import timedelta
 
 from django.core.validators import (
     DecimalValidator, MaxLengthValidator, MaxValueValidator,
@@ -59,6 +60,7 @@ def get(self, *args, **kwargs):
 class ExampleSerializer(serializers.Serializer):
     date = serializers.DateField()
     datetime = serializers.DateTimeField()
+    duration = serializers.DurationField(default=timedelta())
     hstore = serializers.HStoreField()
     uuid_field = serializers.UUIDField(default=uuid.uuid4)