简体   繁体   中英

How to specify optional parameters on a ViewSet @action method?

I've got a ViewSet class with a method like this:

@action(methods=["get"], detail=True, url_path="foo")
def foo(self, request: Request, pk: int) -> Response:
    limit = request.query_params.get("limit")
    if limit is not None:
        limit = int(limit)
    …

I would like to

  1. declare the method so that the generated OpenAPI specification documents this optional parameter,
  2. ideally in such a way that I don't have to manually mess around with pulling out the variable and converting it.

Something like this would be ideal:

def foo(self, _: Request, pk: int, limit: Optional[int] = None) -> Response:

But it doesn't work - limit is just always None .


A solution for point 1 above is to decorate the method some more:

@swagger_auto_schema(
    manual_parameters=[
        openapi.Parameter(
            "limit",
            openapi.IN_QUERY,
            required=False,
            type=openapi.TYPE_INTEGER
        )
    ]
)

To be able to do what you're after, you'd need to capture query string parameters in Django's url mapping, but Django only searches for request path there, and does not take query string parameters into consideration: docs (this goes all the way down to how django maps urls to views, before DRF and view sets come into play)

The only way I can think of to achieve what you want, is to provide limit as a path parameter, not a query string parameter. Then, you could capture limit from the request path and include it into the view method as a parameter, like this:

@action(methods=["get"], detail=True, url_path="foo(?:/(?P<limit>[0-9]+))?")
def foo(self, request: Request, pk: int, limit: Optional[int] = None) -> Response:
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM