Skip to content
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

Use Pydantic BaseModel for QueryParameters doesn't work? #1315

Closed
golgor opened this issue Oct 18, 2024 · 2 comments
Closed

Use Pydantic BaseModel for QueryParameters doesn't work? #1315

golgor opened this issue Oct 18, 2024 · 2 comments
Labels
enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending

Comments

@golgor
Copy link

golgor commented Oct 18, 2024

Describe the bug
I can get both responses and requests to work fine using pydantic by simply using a pydantic BaseModel instead of a rest_framework.serializers.Serializer. However, when I try to do the same for Parameters in a GET-function it doesn't work. I have tried many ways, but either there is no result showing it the Schema generation fails.

I'm currently using:

djangorestframework = "3.15.2"
pydantic = "2.9.2"
drf-spectacular = "0.27.2"
django = "4.2.15"

To Reproduce
Working good:

from drf_spectacular.utils import OpenApiResponse, extend_schema
from pydantic import BaseModel, Field
from rest_framework import serializers
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView


class QueryParamsSerializer(serializers.Serializer):
    limit = serializers.IntegerField(default=100)


class QueryParams(BaseModel):
    limit: int = Field(default=100)


class RestFrameWorkAPIView(APIView):
    """Publically available endpoint to get a list of Device Messages."""

    @extend_schema(
        parameters=[
            QueryParamsSerializer,
        ],
        responses={
            200: OpenApiResponse(response=QueryParams, description="OK"),
        },
    )
    def get(self, request: Request) -> Response:
        """Endpoint that returns a list of data messages send by modules."""
        return Response(status=status.HTTP_200_OK)

image

But if I change from QueryParamsSerializer to QueryParams, I first of all get a type error and it is not possible to generate any schema when I try to open up the SpectacularAPIView.as_view() or SpectacularSwaggerView.as_view().

from drf_spectacular.utils import OpenApiResponse, extend_schema
from pydantic import BaseModel, Field
from rest_framework import serializers
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView


class QueryParamsSerializer(serializers.Serializer):
    limit = serializers.IntegerField(default=100)


class QueryParams(BaseModel):
    limit: int = Field(default=100)


class RestFrameWorkAPIView(APIView):
    """Publically available endpoint to get a list of Device Messages."""

    @extend_schema(
        parameters=[
            QueryParamsSerializer,
        ],
        responses={
            200: OpenApiResponse(response=QueryParams, description="OK"),
        },
    )
    def get(self, request: Request) -> Response:
        """Endpoint that returns a list of data messages send by modules."""
        return Response(status=status.HTTP_200_OK)

I can use the same pydantic class as a response serializer, but not for parameters.

If I try to use a POST-function everything works fine as well.

    @extend_schema(
        request=QueryParams,
        responses={
            200: OpenApiResponse(response=QueryParams, description="OK"),
        },
    )
    def post(self, request: Request) -> Response:
        """Endpoint that returns a list of data messages send by modules."""
        return Response(status=status.HTTP_200_OK)

image

I have also tried to search the documentation about this and also for issues here in the Github repo, as well as extensively trying to interrogate various AI resources and searching on Google.

To be honest, I don't know if this is a bug or if I am doing it wrong, but I honestly feel a bit lost here on how to do in that case. Can anyone please advise?

Expected behavior
That using a pydantic model for query parameters generate the correct schema and swagger view as using a rest_framework.serializers.Serializer.

@tfranzel
Copy link
Owner

Hi,
serializer explosion was added as a convenience feature. Never tought many people would use it. It was never meant to be used indirectly through serializer extensions for other classes like pydantic. However, it turns out not that much was actually missing to make it work.

Keep in mind this is a shortcut of a shortcut and the schema might not be 100%, so give it a sanity check first.

@golgor
Copy link
Author

golgor commented Nov 15, 2024

@tfranzel Awesome, thanks a lot for looking into this.

tfranzel added a commit that referenced this issue Nov 27, 2024
Extend query params explosion of non-DRF serializer #1315
@tfranzel tfranzel added enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending labels Nov 27, 2024
@tfranzel tfranzel closed this as completed Dec 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending
Projects
None yet
Development

No branches or pull requests

2 participants