-
Notifications
You must be signed in to change notification settings - Fork 265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
set responses parm for extend_schema will make auto-discovered query parameters disappeared #407
Comments
hi! is the parameter really missing? i can see the parameter in the operation, however i see a different issue. there happens some kind of name collision for the operation. i get looks like the responses declaration creates that problem but i have to investigate. def test_viewset_list_override(no_warnings):
class XViewset(viewsets.ReadOnlyModelViewSet):
queryset = SimpleModel.objects.all()
serializer_class = SimpleSerializer
@extend_schema(
parameters=[
OpenApiParameter(
"format",
OpenApiTypes.INT,
location=OpenApiParameter.QUERY,
required=True,
)
],
responses={(200, "*/*"): OpenApiTypes.STR},
)
def list(self, request, *args, **kwargs):
pass # pragma: no cover
schema = generate_schema('/x', XViewset)
assert schema['paths']['/x/']['get']['parameters'][0]['name'] == 'format' # OK
assert schema['paths']['/x/']['get']['operationId'] == 'x_list' # FAIL
assert schema['paths']['/x/{id}/']['get']['operationId'] == 'x_retrieve' #FAIL |
so it turns out that you override the list detection by doing we cannot change this, as it breaks a dozen other things. what you can do is set an explicit |
Set an explicit operationId='x_list' is not working, the So this is definitely a bug.
Maybe we can change the detection order,for example: from if is_basic_type(serializer):
return False
if hasattr(self.view, 'action'):
return self.view.action == 'list' to if hasattr(self.view, 'action'):
return self.view.action == 'list'
if is_basic_type(serializer):
return False The best solution is providing an option to include the filter parameters because
def get_filter_parameters(self, path, method):
if not self.allows_filters(path, method):
return []
parameters = []
for filter_backend in self.view.filter_backends:
parameters += filter_backend().get_schema_operation_parameters(self.view)
return parameters
def allows_filters(self, path, method):
"""
Determine whether to include filter Fields in schema.
Default implementation looks for ModelViewSet or GenericAPIView
actions/methods that cause filtering on the default implementation.
"""
if getattr(self.view, 'filter_backends', None) is None:
return False
if hasattr(self.view, 'action'):
return self.view.action in ["list", "retrieve", "update", "partial_update", "destroy"]
return method.lower() in ["get", "put", "patch", "delete"] |
Hi @tfranzel, I also encountered the same issue of filterset query parameters not being detected when using manually set responses via To Reproduce import django_filters
from django_filters.rest_framework import DjangoFilterBackend
class PDFRenderer(renderers.BaseRenderer):
media_type = 'application/pdf'
format = 'pdf'
charset = None
render_style = 'binary'
def render(self, data, media_type=None, renderer_context=None):
return data
class SimpleFilterSet(django_filters.FilterSet):
class Meta:
model = SimpleModel
fields = {
'id': ['in'],
}
class XViewset(viewsets.GenericViewSet):
queryset = SimpleModel.objects.all()
serializer_class = SimpleSerializer
filterset_class = SimpleFilterSet
filter_backends = [DjangoFilterBackend]
renderers = [PDFRenderer]
@extend_schema(
# without explicit operation_id, this operation is detected as non-list and thus
# will be named "x_retrieve", which create a collision with the actual retrieve.
operation_id='x_list',
responses={(200, 'application/pdf'): OpenApiTypes.BINARY},
)
def list(self, request, *args, **kwargs):
pass # pragma: no cover Which produces the following schema paths:
/x/:
get:
operationId: x_list
responses:
'200':
content:
application/pdf:
schema:
format: binary
type: string
description: ''
security:
- cookieAuth: []
- basicAuth: []
- {}
tags:
- x |
So I had another look and I think I now have a better undestanding of the problem. It is a bit of an unfortunate situation though. Any changes to It is true that Imho the problem is that we currently have no way of enabling the detected filters (not manually defined) when the response is clearly not a list. So basically a selective way to disable our "simplifiying assumption". The |
Thanks for the response. That's unfortunate though. |
Not saying we won't fix it! Actually I think its not too bad. We can fix this. It's just not going to be an "automatic" fix, but that is not really a issue since your are already doing something manually by using |
@extend_schema(
responses={(200, 'application/pdf'): OpenApiTypes.BINARY},
filters=True,
) is the preferred way to enable filters for non-list responses. This can also be used as suppression with This does not touch list detection itself, since spectacular imho does the right thing here already. Depending on your case, you may also need the |
Thank you so much! I've checked and it works wonderfully for me. |
closing this issue for now. feel free to comment if anything is missing or not working and we will follow-up. |
Describe the bug
set responses parm for extend_schema will make auto-discovered query parameters disappeared
To Reproduce
Expected behavior
Auto-discovered query parameters exist as normal
The text was updated successfully, but these errors were encountered: