Skip to content

Commit 061e0ed

Browse files
authored
Added url and schema_url arguments (#4321)
1 parent 6a7d34e commit 061e0ed

File tree

4 files changed

+39
-11
lines changed

4 files changed

+39
-11
lines changed

docs/api-guide/schemas.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,11 @@ that include the Core JSON media type in their `Accept` header.
128128
This is a great zero-configuration option for when you want to get up and
129129
running really quickly.
130130

131-
The only other available option to `DefaultRouter` is `schema_renderers`, which
132-
may be used to pass the set of renderer classes that can be used to render
133-
schema output.
131+
The other available options to `DefaultRouter` are:
132+
133+
#### schema_renderers
134+
135+
May be used to pass the set of renderer classes that can be used to render schema output.
134136

135137
from rest_framework.renderers import CoreJSONRenderer
136138
from my_custom_package import APIBlueprintRenderer
@@ -139,6 +141,17 @@ schema output.
139141
CoreJSONRenderer, APIBlueprintRenderer
140142
])
141143

144+
#### schema_url
145+
146+
May be used to pass the root URL for the schema. This can either be used to ensure that
147+
the schema URLs include a canonical hostname and schema, or to ensure that all the
148+
schema URLs include a path prefix.
149+
150+
router = DefaultRouter(
151+
schema_title='Server Monitoring API',
152+
schema_url='https://www.example.org/api/'
153+
)
154+
142155
If you want more flexibility over the schema output then you'll need to consider
143156
using `SchemaGenerator` instead.
144157

@@ -264,6 +277,7 @@ Typically you'll instantiate `SchemaGenerator` with a single argument, like so:
264277
Arguments:
265278

266279
* `title` - The name of the API. **required**
280+
* `url` - The root URL of the API schema. This option is not required unless the schema is included under path prefix.
267281
* `patterns` - A list of URLs to inspect when generating the schema. Defaults to the project's URL conf.
268282
* `urlconf` - A URL conf module name to use when generating the schema. Defaults to `settings.ROOT_URLCONF`.
269283

rest_framework/compat.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
from django.utils import importlib # Will be removed in Django 1.9
2424

2525

26+
try:
27+
import urlparse # Python 2.x
28+
except ImportError:
29+
import urllib.parse as urlparse
30+
31+
2632
def unicode_repr(instance):
2733
# Get the repr of an instance, but ensure it is a unicode string
2834
# on both python 3 (already the case) and 2 (not the case).

rest_framework/routers.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,14 @@ class DefaultRouter(SimpleRouter):
278278
def __init__(self, *args, **kwargs):
279279
if 'schema_renderers' in kwargs:
280280
assert 'schema_title' in kwargs, 'Missing "schema_title" argument.'
281+
if 'schema_url' in kwargs:
282+
assert 'schema_title' in kwargs, 'Missing "schema_title" argument.'
281283
self.schema_title = kwargs.pop('schema_title', None)
284+
self.schema_url = kwargs.pop('schema_url', None)
282285
self.schema_renderers = kwargs.pop('schema_renderers', self.default_schema_renderers)
283286
super(DefaultRouter, self).__init__(*args, **kwargs)
284287

285-
def get_api_root_view(self, schema_urls=None):
288+
def get_api_root_view(self, api_urls=None):
286289
"""
287290
Return a view to use as the API root.
288291
"""
@@ -294,11 +297,12 @@ def get_api_root_view(self, schema_urls=None):
294297
view_renderers = list(api_settings.DEFAULT_RENDERER_CLASSES)
295298
schema_media_types = []
296299

297-
if schema_urls and self.schema_title:
300+
if api_urls and self.schema_title:
298301
view_renderers += list(self.schema_renderers)
299302
schema_generator = SchemaGenerator(
300303
title=self.schema_title,
301-
patterns=schema_urls
304+
url=self.schema_url,
305+
patterns=api_urls
302306
)
303307
schema_media_types = [
304308
renderer.media_type
@@ -347,7 +351,7 @@ def get_urls(self):
347351
urls = super(DefaultRouter, self).get_urls()
348352

349353
if self.include_root_view:
350-
view = self.get_api_root_view(schema_urls=urls)
354+
view = self.get_api_root_view(api_urls=urls)
351355
root_url = url(r'^$', view, name=self.root_view_name)
352356
urls.append(root_url)
353357

rest_framework/schemas.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from django.utils import six
77

88
from rest_framework import exceptions, serializers
9-
from rest_framework.compat import coreapi, uritemplate
9+
from rest_framework.compat import coreapi, uritemplate, urlparse
1010
from rest_framework.request import clone_request
1111
from rest_framework.views import APIView
1212

@@ -57,7 +57,7 @@ class SchemaGenerator(object):
5757
'delete': 'destroy',
5858
}
5959

60-
def __init__(self, title=None, patterns=None, urlconf=None):
60+
def __init__(self, title=None, url=None, patterns=None, urlconf=None):
6161
assert coreapi, '`coreapi` must be installed for schema support.'
6262

6363
if patterns is None and urlconf is not None:
@@ -70,7 +70,11 @@ def __init__(self, title=None, patterns=None, urlconf=None):
7070
urls = import_module(settings.ROOT_URLCONF)
7171
patterns = urls.urlpatterns
7272

73+
if url and not url.endswith('/'):
74+
url += '/'
75+
7376
self.title = title
77+
self.url = url
7478
self.endpoints = self.get_api_endpoints(patterns)
7579

7680
def get_schema(self, request=None):
@@ -102,7 +106,7 @@ def get_schema(self, request=None):
102106
insert_into(content, key, link)
103107

104108
# Return the schema document.
105-
return coreapi.Document(title=self.title, content=content)
109+
return coreapi.Document(title=self.title, content=content, url=self.url)
106110

107111
def get_api_endpoints(self, patterns, prefix=''):
108112
"""
@@ -203,7 +207,7 @@ def get_link(self, path, method, callback):
203207
encoding = None
204208

205209
return coreapi.Link(
206-
url=path,
210+
url=urlparse.urljoin(self.url, path),
207211
action=method.lower(),
208212
encoding=encoding,
209213
fields=fields

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy