Adjust ManualSchema to take fields

… and `description`.

Allows `url` and `action` to remain dynamic
This commit is contained in:
Carlton Gibson 2017-09-14 10:10:05 +02:00
parent 35e058cdb1
commit a7b2f50ffe
3 changed files with 101 additions and 25 deletions

View File

@ -199,17 +199,28 @@ To customise the `Link` generation you may:
This provides complete control over view introspection. This provides complete control over view introspection.
* Instantiate `ManualSchema` on your view, providing the Core API `Link` * Instantiate `ManualSchema` on your view, providing the Core API `Fields` for
explicitly: the view explicitly:
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.schemas import ManualSchema from rest_framework.schemas import ManualSchema
class CustomView(APIView): class CustomView(APIView):
... ...
schema = ManualSchema( schema = ManualSchema(fields=[
coreapi.Link(...) coreapi.Field(
) "first_field",
required=True,
location="path",
schema=coreschema.String()
),
coreapi.Field(
"second_field",
required=True,
location="path",
schema=coreschema.String()
),
])
This allows manually specifying the schema for some views whilst maintaining This allows manually specifying the schema for some views whilst maintaining
automatic generation elsewhere. automatic generation elsewhere.
@ -580,17 +591,31 @@ Return a list of `coreapi.Link()` instances, as returned by the `get_schema_fiel
## ManualSchema ## ManualSchema
Allows specifying a manual schema for a view: Allows manually providing a list of `coreapi.Field` instances for the schema,
plus an optional description.
class MyView(APIView): class MyView(APIView):
schema = ManualSchema(coreapi.Link( schema = ManualSchema(fields=[
url='/example/', coreapi.Field(
action='get', "first_field",
fields=[] required=True,
)) location="path",
schema=coreschema.String()
),
coreapi.Field(
"second_field",
required=True,
location="path",
schema=coreschema.String()
),
]
)
The `ManualSchema` constructor takes a single parameter `link`, The `ManualSchema` constructor takes two arguments:
the `coreapi.Link` instance for the view.
**`fields`**: A list of `coreapi.Field` instances. Required.
**`description`**: A string description. Optional.
--- ---

View File

@ -364,11 +364,31 @@ class AutoSchema(ViewInspector):
class ManualSchema(ViewInspector): class ManualSchema(ViewInspector):
""" """
Overrides get_link to return manually specified schema. Allows providing a list of coreapi.Fields,
plus an optional description.
""" """
def __init__(self, link): def __init__(self, fields, description=''):
assert isinstance(link, coreapi.Link) """
self._link = link Parameters:
* `fields`: list of `coreapi.Field` instances.
* `descripton`: String description for view. Optional.
"""
assert all(isinstance(f, coreapi.Field) for f in fields), "`fields` must be a list of coreapi.Field instances"
self._fields = fields
self._description = description
def get_link(self, path, method, base_url):
if base_url and path.startswith('/'):
path = path[1:]
return coreapi.Link(
url=urlparse.urljoin(base_url, path),
action=method.lower(),
encoding=None,
fields=self._fields,
description=self._description
)
def get_link(self, *args):
return self._link return self._link

View File

@ -534,15 +534,46 @@ class TestDescriptor(TestCase):
def test_view_with_manual_schema(self): def test_view_with_manual_schema(self):
expected = coreapi.Link( path = '/example'
url='/example/', method = 'get'
action='get', base_url = None
fields=[]
) fields = [
coreapi.Field(
"first_field",
required=True,
location="path",
schema=coreschema.String()
),
coreapi.Field(
"second_field",
required=True,
location="path",
schema=coreschema.String()
),
coreapi.Field(
"third_field",
required=True,
location="path",
schema=coreschema.String()
),
]
description = "A test endpoint"
class CustomView(APIView): class CustomView(APIView):
schema = ManualSchema(expected) """
ManualSchema takes list of fields for endpoint.
- Provides url and action, which are always dynamic
"""
schema = ManualSchema(fields, description)
expected = coreapi.Link(
url=path,
action=method,
fields=fields,
description=description
)
view = CustomView() view = CustomView()
link = view.schema.get_link() link = view.schema.get_link(path, method, base_url)
assert link == expected assert link == expected