1
1
import warnings
2
+ from operator import attrgetter
2
3
from urllib .parse import urljoin
3
4
4
5
from django .core .validators import (
8
9
from django .db import models
9
10
from django .utils .encoding import force_str
10
11
11
- from rest_framework import exceptions , serializers
12
+ from rest_framework import exceptions , renderers , serializers
12
13
from rest_framework .compat import uritemplate
13
14
from rest_framework .fields import _UnvalidatedField , empty
14
15
@@ -78,7 +79,9 @@ def get_schema(self, request=None, public=False):
78
79
79
80
class AutoSchema (ViewInspector ):
80
81
81
- content_types = ['application/json' ]
82
+ request_media_types = []
83
+ response_media_types = []
84
+
82
85
method_mapping = {
83
86
'get' : 'Retrieve' ,
84
87
'post' : 'Create' ,
@@ -339,6 +342,12 @@ def _map_field(self, field):
339
342
self ._map_min_max (field , content )
340
343
return content
341
344
345
+ if isinstance (field , serializers .FileField ):
346
+ return {
347
+ 'type' : 'string' ,
348
+ 'format' : 'binary'
349
+ }
350
+
342
351
# Simplest cases, default to 'string' type:
343
352
FIELD_CLASS_SCHEMA_TYPE = {
344
353
serializers .BooleanField : 'boolean' ,
@@ -434,9 +443,20 @@ def _get_paginator(self):
434
443
pagination_class = getattr (self .view , 'pagination_class' , None )
435
444
if pagination_class :
436
445
return pagination_class ()
437
-
438
446
return None
439
447
448
+ def map_parsers (self , path , method ):
449
+ return list (map (attrgetter ('media_type' ), self .view .parser_classes ))
450
+
451
+ def map_renderers (self , path , method ):
452
+ media_types = []
453
+ for renderer in self .view .renderer_classes :
454
+ # BrowsableAPIRenderer not relevant to OpenAPI spec
455
+ if renderer == renderers .BrowsableAPIRenderer :
456
+ continue
457
+ media_types .append (renderer .media_type )
458
+ return media_types
459
+
440
460
def _get_serializer (self , method , path ):
441
461
view = self .view
442
462
@@ -456,6 +476,8 @@ def _get_request_body(self, path, method):
456
476
if method not in ('PUT' , 'PATCH' , 'POST' ):
457
477
return {}
458
478
479
+ self .request_media_types = self .map_parsers (path , method )
480
+
459
481
serializer = self ._get_serializer (path , method )
460
482
461
483
if not isinstance (serializer , serializers .Serializer ):
@@ -473,7 +495,7 @@ def _get_request_body(self, path, method):
473
495
return {
474
496
'content' : {
475
497
ct : {'schema' : content }
476
- for ct in self .content_types
498
+ for ct in self .request_media_types
477
499
}
478
500
}
479
501
@@ -486,6 +508,8 @@ def _get_responses(self, path, method):
486
508
}
487
509
}
488
510
511
+ self .response_media_types = self .map_renderers (path , method )
512
+
489
513
item_schema = {}
490
514
serializer = self ._get_serializer (path , method )
491
515
@@ -513,7 +537,7 @@ def _get_responses(self, path, method):
513
537
'200' : {
514
538
'content' : {
515
539
ct : {'schema' : response_schema }
516
- for ct in self .content_types
540
+ for ct in self .response_media_types
517
541
},
518
542
# description is a mandatory property,
519
543
# https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responseObject
0 commit comments