My APIView returns following object:
out = {
"foo": FooSerializer(foo, many=True).data,
"bar": BarSerializer(bar, many=True).data
}
Trying to represent that object by using Serializer references fails with TypeError: Object of type 'SerializerMetaclass' is not JSON serializable:
@swagger_auto_schema(responses={
200: openapi.Response('OK', openapi.Schema(type=openapi.TYPE_OBJECT, properties={
'foo': FooSerializer,
'bar': BarSerializer
})),
})
Additionally, I don't have these Serializers used anywhere else, so they don't register themselves as definitions, so following fails too:
@swagger_auto_schema(responses={
200: openapi.Response('OK', openapi.Schema(type=openapi.TYPE_OBJECT, properties={
'foo': openapi.SchemaRef(openapi.ReferenceResolver('definitions'), 'Foo'),
'bar': openapi.SchemaRef(openapi.ReferenceResolver('definitions'), 'Bar')
})),
})
Seems that in such case, defining the whole response structure is the only option, or am I missing some trick here?
Thanks!
Hello,
Sadly, no, there is currently no such mechanism implemented for recursively converting Serializers inside a Schema object.
Unless you have a good reason not to, it's probably better to use a single serializer for your view result (drf-yasg limitations or not):
class FooBarSerializer(Serializer):
foo = FooSerializer(many=True)
bar = BarSerializer(many=True)
out = FooBarSerializer({'foo': foo, 'bar': bar}).data
@swagger_auto_schema(responses={
200: openapi.Response('OK', FooBarSerializer),
})
Yes, this is where I am headed right now 馃槈
But what about using SchemaRef? Is there a way to "pre-register" schemas based on Serializers?
Unfortunately not, since some aspects of Serializer to Schema conversion can depend on runtime parameters (i.e. the user who is requesting the swagger definition).
Also do note that there is no global ReferenceResolver, and your last example is wrong in any situation because it always tries to get a definition from an empty ReferenceResolver. The instance that is actually used is created for every new run of get_schema, here.
Okay, now I get it - I saw docstring for Schema mentioning SchemaRef and tried to just use it w/o fully understanding the context!
@axnsan12 would it be possible to inspect a serializer class that is not used by any view to include it manually in the Model definitions ? if so, how? I've been looking at the code but still having a hard time trying to do so.
Thanks!
I gotta say I don't quite understand the logic.
If a Schema instance can be substituted with a Serializer instance in a Response, then why not in a Schema property?
Most helpful comment
Hello,
Sadly, no, there is currently no such mechanism implemented for recursively converting
Serializers inside aSchemaobject.Unless you have a good reason not to, it's probably better to use a single serializer for your view result (
drf-yasglimitations or not):