-
Notifications
You must be signed in to change notification settings - Fork 266
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
Annotate @extend_schema
to accept a list of integers
#1174
Comments
Hey John, I was always reluctant to add this because I feared people would abuse it and shoot themselves in the foot instead of properly using This came of course at the expense of this very valid use-case. You may have noticed it already works for basic types, just not I'll have a look at it again, because I'm not sure anymore if that was an overly cautious decision or not. |
Yep, we've used it for |
@tfranzel In my case I simply went ahead and created a serializer with a single So for me, I'm personally okay to close this issue if you are, since this is somewhat a fundamental limitation of DRF itself. |
Add support for direct usage of higher order hints #1174
Hi, Thanks for your time on this issue, that's exactly what I was looking for ! 🤗 As of today, my team is enforcing the use of serializers before returning back data. MyResponseSerializerField = serializers.ListField(child=serializers.Integer())
def view():
data_to_return = [0, 1, 2]
serialized_data = MyResponseSerializerField.to_representation(data_to_return)
return Response(data=serialized_data) It would be awesome to reuse MyResponseSerializerField = serializers.ListField(child=serializers.Integer())
@extend_schema(responses={200: MyResponseSerializerField})
def view():
data_to_return = [0, 1, 2]
serialized_data = MyResponseSerializerField.to_representation(data_to_return)
return Response(data=serialized_data) As of today, we're using this : @extend_schema(
responses={
200: AutoSchema()._map_serializer_field(MyResponseSerializerField, "response"),
},
) It works well, but it's not very nice. Do you think it's possible to accept serializer fields in responses ? |
I figured out my previous proposition was not working well for many spectacular use cases, especially because of the "list" mechanism that is a condition for many features to work (filters, examples, ...). As pointed by @johnthagen, the limitation comes from DRF so I opted for a DRF-side fix. from __future__ import annotations
import typing
from drf_spectacular.extensions import OpenApiSerializerExtension
from rest_framework import serializers
if typing.TYPE_CHECKING:
from drf_spectacular.openapi import AutoSchema
from drf_spectacular.utils import Direction, _SchemaType
class FieldSerializer(serializers.Serializer):
child: serializers.Field = None
def to_internal_value(self, data):
return self.fields["child"].to_internal_value(data)
def to_representation(self, instance):
return self.fields["child"].to_representation(instance)
class FieldSerializerOpenApiExtension(OpenApiSerializerExtension):
target_class = FieldSerializer
match_subclasses = True
def map_serializer(self, auto_schema: AutoSchema, direction: Direction) -> _SchemaType:
return auto_schema._map_serializer_field(self.target.fields["child"], direction=direction) I'm now able to declare serializers with unique fields, and so to leverage the class MyIdsSerializer(FieldSerializer):
child = serializers.IntegerField()
@extend_schema(responses={200: MyIdsSerializer(many=True)})
def view():
data = [0, 1, 2]
serialized_data = MyIdsSerializer(data, many=True)
return Response(data=serialized_data) |
I'd roughly like to express that my API endpoint directly accepts a list of integers (in my case they will be a list of IDs in the POST body to operate on). The input to the endpoint would look like:
What I roughly would like to do is:
but a
ListField
isn't an actualSerializer
.I also tried
But both print out the warning
I think this is similar to Pydantic'c concept of a
RootModel
Is there a way to express this to
drf-spectacular
?The text was updated successfully, but these errors were encountered: