This commit is contained in:
Iliyan Angelov
2025-09-19 11:58:53 +03:00
parent 306b20e24a
commit 6b247e5b9f
11423 changed files with 1500615 additions and 778 deletions

View File

@@ -0,0 +1,50 @@
from drf_spectacular.drainage import set_override, warn
from drf_spectacular.extensions import OpenApiSerializerExtension
from drf_spectacular.plumbing import ResolvedComponent, build_basic_type
from drf_spectacular.types import OpenApiTypes
class PydanticExtension(OpenApiSerializerExtension):
"""
Allows using pydantic models on @extend_schema(request=..., response=...) to
describe your API.
We only have partial support for pydantic's version of dataclass, due to the way they
are designed. The outermost class (the @extend_schema argument) has to be a subclass
of pydantic.BaseModel. Inside this outermost BaseModel, any combination of dataclass
and BaseModel can be used.
"""
target_class = "pydantic.BaseModel"
match_subclasses = True
def get_name(self, auto_schema, direction):
# due to the fact that it is complicated to pull out every field member BaseModel class
# of the entry model, we simply use the class name as string for object. This hack may
# create false positive warnings, so turn it off. However, this may suppress correct
# warnings involving the entry class.
# TODO suppression may be migrated to new ComponentIdentity system
set_override(self.target, 'suppress_collision_warning', True)
return self.target.__name__
def map_serializer(self, auto_schema, direction):
# let pydantic generate a JSON schema
try:
from pydantic.json_schema import model_json_schema
except ImportError:
warn("Only pydantic >= 2 is supported. defaulting to generic object.")
return build_basic_type(OpenApiTypes.OBJECT)
schema = model_json_schema(self.target, ref_template="#/components/schemas/{model}", mode="serialization")
# pull out potential sub-schemas and put them into component section
for sub_name, sub_schema in schema.pop("$defs", {}).items():
component = ResolvedComponent(
name=sub_name,
type=ResolvedComponent.SCHEMA,
object=sub_name,
schema=sub_schema,
)
auto_schema.registry.register_on_missing(component)
return schema