@extend_schema has no effect on GET/retrieve extra actions in a ModelViewSet
See original GitHub issueDRF v3.11.1 drf-spectacular v0.15.0
When adding an extra GET
action (not merely overriding create
or retrieve
) in a ModelViewSet
and decorating it with @extend_schema
, the specified request serializer is not represented as a component
in the generated schema.
In the example below, the search/
endpoint shows up under paths
, but the fields under SearchRequestSerializer
are not included under components/schemas
. Changing the action to a POST
method instead of a GET
resolves the issue, but I believe the method really should be a GET
.
Example View and method:
class MyObjectViewSet(viewsets.ModelViewSet):
http_method_names = ['get', 'post']
serializer_class = MyObjectSerializer
@sensitive_variables('access_token')
@extend_schema(
request=SearchRequestSerializer,
responses={
(200,'application/gzip'): OpenApiTypes.BINARY,
401: OpenApiResponse(response=GeneralResponseSerializer),
404: OpenApiResponse(response=GeneralResponseSerializer)
},
)
@action(detail=False, methods=['GET'])
def search(self, request):
data = SearchRequestSerializer(data=self.request.query_params)
data.is_valid(raise_exception=True)
...
return response
Excerpt from the generated schema (as a GET):
paths:
/api/documents/search/:
get:
operationId: documents_search_retrieve
tags:
- documents
security:
- basicAuth: []
- tokenAuth: []
- {}
responses:
'200':
content:
application/gzip:
schema:
type: string
format: binary
description: ''
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralResponse'
description: null
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralResponse'
description: null
Excerpt from the generated schema (if I change it to a POST):
/api/documents/search/:
post:
operationId: documents_search_create
tags:
- documents
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SearchRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SearchRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/SearchRequest'
required: true
security:
- basicAuth: []
- tokenAuth: []
- {}
responses:
'200':
content:
application/gzip:
schema:
type: string
format: binary
description: ''
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralResponse'
description: null
'404':
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralResponse'
description: null
...
components:
schemas:
SearchRequest:
<details from the SearchRequest serializer>
I would expect a component
called SearchRequest
to be included in the schema, along with the field metadata defined in SearchRequestSerializer
.
I realize I may be misunderstanding the expected behavior here. If so, I could really use a pointer in the right direction.
Issue Analytics
- State:
- Created a year ago
- Comments:5 (3 by maintainers)
Yes it does- thank you very much! I didn’t understand the distinction between the
request
andparameters
args and how they correlate to the HTTP structures.I assumed versions would be more tightly coupled, but I’ll go ahead and update in my dev environment today.
Thanks for your help!
you can update spectacular regardless. Our latest version supports
DRF>=3.10.4
which is clearly the case for your DRF version.