-
Notifications
You must be signed in to change notification settings - Fork 270
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
Custom GET "action" endpoint not displaying query params #435
Comments
Hi @jourdanrodrigues! filters and pagination are always defined as lists by DRF. at least that is how i understand it. of course it can make sense to have parameters in a non-list case but that is not what the filterset classes were designed for afaik. i'm not sure how we should support that. changing the list mechanics as you did there will likely break hundreds of users, so we cannot do this. as you can see in CI, this break half of all the tests. This function is already finely tuned and is hard to change at all. |
Yep, that was almost a total failure. Hahaha I see. I also exhausted my options as I've been poking here and there for a few hours now and couldn't find a way to bypass those checks. |
what you can do is either annotate those parameters manually with |
drf-spectacular/drf_spectacular/openapi.py Line 367 in deb8325
is where you would insert something that bypasses |
Thanks for the clarification, @tfranzel! I finally managed to get it working. I actually made a mistake in that PR I sent. Here's the snipper for historical purpose: from drf_spectacular.extensions import OpenApiFilterExtension
from drf_spectacular.openapi import AutoSchema as SpectacularAutoSchema
class AutoSchema(SpectacularAutoSchema):
def _get_filter_parameters(self):
if not (self._is_a_general_list_view() or self._is_list_view()):
return []
if getattr(self.view, 'filter_backends', None) is None:
return []
parameters = []
for filter_backend in self.view.filter_backends:
filter_extension = OpenApiFilterExtension.get_match(filter_backend())
if filter_extension:
parameters += filter_extension.get_schema_operation_parameters(self)
else:
parameters += filter_backend().get_schema_operation_parameters(self.view)
return parameters
def _is_a_general_list_view(self):
return hasattr(self.view, "detail") and self.method.lower() == "get" and not self.view.detail |
awesome! that is how i roughly imagined it. glad you got it working. |
@tfranzel I think we should reconsider pushing this to upstream. It is more of a common problem. I've been using actions to perform bulk tasks on listed objects (similar to Django admin actions). |
That is a different thing.
I disagree. How would you do this without breaking everything? And the general statement still holds that DRF does not define filter backend parameters on non-list views. |
This is how I solved it
|
Hey guys, @andriijas comment just reminded me that we did fix this issue a couple of month later in Oct '21 with #407 @realsuayip sry I totally forgot about this. We added a @jourdanrodrigues hopefully this is still useful to you. Your hack hasn't been necessary for quite some time now, if you use the @extend_schema(
responses=ItemStatsSerializer(),
filters=True,
)
@action(detail=False, methods=["get"])
def stats(self, request, *args, **kwargs):
... |
Thanks, that cleaned up my messy example. It was a pleasent learning experience though :D |
Works like a charm @tfranzel . We used it for the same logic, represents some totals/summary/counts with ability to filter before this aggregation 👍 Just adding I would just request you guys to add this info in README somewhere for future reference as it is kind of common approach 🚀 |
Describe the bug
Query params don't show up in an "@action" that doesn't take a list serializer class.
I understand the point of view here of query params being for listing resources, but I'd like to know if there's any way to bypass this check to load the query params anyway.
To Reproduce
This won't display query params.
Expected behavior
Should display query params correctly.
After a quick look at the code, seems like if
if is_list_serializer(serializer)
andif hasattr(self.view, 'action')
happen afterif isinstance(self.view, ListModelMixin)
atdrf_spectacular.openapi.AutoSchema._is_list_view
, then it'd render the query params alright.The text was updated successfully, but these errors were encountered: