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.
* Instantiate `ManualSchema` on your view, providing the Core API `Link`
explicitly:
* Instantiate `ManualSchema` on your view, providing the Core API `Fields` for
the view explicitly:
from rest_framework.views import APIView
from rest_framework.schemas import ManualSchema
class CustomView(APIView):
...
schema = ManualSchema(
coreapi.Link(...)
)
schema = ManualSchema(fields=[
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
automatic generation elsewhere.
@ -580,17 +591,31 @@ Return a list of `coreapi.Link()` instances, as returned by the `get_schema_fiel
## 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):
schema = ManualSchema(coreapi.Link(
url='/example/',
action='get',
fields=[]
))
schema = ManualSchema(fields=[
coreapi.Field(
"first_field",
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 `coreapi.Link` instance for the view.
The `ManualSchema` constructor takes two arguments:
**`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):
"""
Overrides get_link to return manually specified schema.
Allows providing a list of coreapi.Fields,
plus an optional description.
"""
def __init__(self, link):
assert isinstance(link, coreapi.Link)
self._link = link
def __init__(self, fields, description=''):
"""
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

View File

@ -534,15 +534,46 @@ class TestDescriptor(TestCase):
def test_view_with_manual_schema(self):
expected = coreapi.Link(
url='/example/',
action='get',
fields=[]
)
path = '/example'
method = 'get'
base_url = None
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):
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()
link = view.schema.get_link()
link = view.schema.get_link(path, method, base_url)
assert link == expected