Repository: marshmallow-code/apispec

Issue:
Update Custom Fields docs for #435
 https://github.com/marshmallow-code/apispec/pull/435#issuecomment-486654039

Comments:

Patch:
diff --git a/docs/using_plugins.rst b/docs/using_plugins.rst
index ad9007b..b9bed1b 100644
--- a/docs/using_plugins.rst
+++ b/docs/using_plugins.rst
@@ -232,35 +232,36 @@ apispec will respect schema modifiers such as ``exclude`` and ``partial`` in the
 Custom Fields
 ***************
 
-By default, apispec only knows how to set the type of
-built-in marshmallow fields. If you want to generate definitions for
-schemas with custom fields, use the
-`apispec.ext.marshmallow.MarshmallowPlugin.map_to_openapi_type` decorator.
+By default, apispec knows how to map class of the provided marshmallow fields to the
+correct OpenAPI type. If your custom field sub-classes a standard marshmallow field
+class then it will inherit the default mapping. If you want to override the OpenAPI
+type in the generated definitions for schemas with custom fields, use the
+`apispec.ext.marshmallow.MarshmallowPlugin.map_to_openapi_type` decorator. This can
+be invoked with either a pair of strings which provide the OpenAPI type, or a
+marshmallow field that has the same target mapping.
 
 .. code-block:: python
 
     from apispec import APISpec
     from apispec.ext.marshmallow import MarshmallowPlugin
-    from marshmallow.fields import Integer
+    from marshmallow.fields import Integer, Field
 
     ma_plugin = MarshmallowPlugin()
 
-    spec = APISpec(
-        title="Gisty",
-        version="1.0.0",
-        openapi_version="3.0.2",
-        info=dict(description="A minimal gist API"),
-        plugins=[ma_plugin],
-    )
+
+    # Inherits Integer mapping of ('integer', 'int32')
+    class MyCustomInteger(Integer):
+        pass
 
 
+    # Override Integer mapping
     @ma_plugin.map_to_openapi_type("string", "uuid")
     class MyCustomField(Integer):
         pass
 
 
     @ma_plugin.map_to_openapi_type(Integer)  # will map to ('integer', 'int32')
-    class MyCustomFieldThatsKindaLikeAnInteger(Integer):
+    class MyCustomFieldThatsKindaLikeAnInteger(Field):
         pass
 
 
diff --git a/src/apispec/ext/marshmallow/__init__.py b/src/apispec/ext/marshmallow/__init__.py
index d96537a..230b674 100644
--- a/src/apispec/ext/marshmallow/__init__.py
+++ b/src/apispec/ext/marshmallow/__init__.py
@@ -36,6 +36,7 @@ from __future__ import absolute_import
 import warnings
 
 from apispec import BasePlugin
+from apispec.compat import itervalues
 from .common import resolve_schema_instance, make_schema_key
 from .openapi import OpenAPIConverter
 
@@ -123,11 +124,11 @@ class MarshmallowPlugin(BasePlugin):
         # OAS 3 component except header
         if self.openapi_version.major >= 3:
             if "content" in data:
-                for content_type in data["content"]:
-                    schema = data["content"][content_type]["schema"]
-                    data["content"][content_type][
-                        "schema"
-                    ] = self.openapi.resolve_schema_dict(schema)
+                for content in itervalues(data["content"]):
+                    if "schema" in content:
+                        content["schema"] = self.openapi.resolve_schema_dict(
+                            content["schema"]
+                        )
 
     def map_to_openapi_type(self, *args):
         """Decorator to set mapping for custom fields.


Test patch:
diff --git a/tests/test_ext_marshmallow.py b/tests/test_ext_marshmallow.py
index c1f2d0e..bac008e 100644
--- a/tests/test_ext_marshmallow.py
+++ b/tests/test_ext_marshmallow.py
@@ -245,6 +245,13 @@ class TestComponentResponseHelper:
         assert resolved_schema["properties"]["name"]["type"] == "string"
         assert resolved_schema["properties"]["password"]["type"] == "string"
 
+    @pytest.mark.parametrize("spec", ("3.0.0",), indirect=True)
+    def test_content_without_schema(self, spec):
+        resp = {"content": {"application/json": {"example": {"name": "Example"}}}}
+        spec.components.response("GetPetOk", resp)
+        response = get_responses(spec)["GetPetOk"]
+        assert response == resp
+
 
 class TestCustomField:
     def test_can_use_custom_field_decorator(self, spec_fixture):