diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index dc120d8e8..9a361227e 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -229,7 +229,7 @@ class PageNumberPagination(BasePagination): ('results', data) ])) - def get_paginated_response_schema(self, schema): + def get_paginated_response_schema(self, schema, url='/accounts/', domain='api.example.org', protocol='http'): return { 'type': 'object', 'properties': { @@ -241,15 +241,15 @@ class PageNumberPagination(BasePagination): 'type': 'string', 'nullable': True, 'format': 'uri', - 'example': 'http://api.example.org/accounts/?{page_query_param}=4'.format( - page_query_param=self.page_query_param) + 'example': '{protocol}://{domain}{url}?{page_query_param}=4'.format( + page_query_param=self.page_query_param, protocol=protocol, domain=domain, url=url) }, 'previous': { 'type': 'string', 'nullable': True, 'format': 'uri', - 'example': 'http://api.example.org/accounts/?{page_query_param}=2'.format( - page_query_param=self.page_query_param) + 'example': '{protocol}://{domain}{url}?{page_query_param}=2'.format( + page_query_param=self.page_query_param, protocol=protocol, domain=domain, url=url) }, 'results': schema, }, @@ -402,7 +402,7 @@ class LimitOffsetPagination(BasePagination): ('results', data) ])) - def get_paginated_response_schema(self, schema): + def get_paginated_response_schema(self, schema, url='/accounts/', domain='api.example.org', protocol='http'): return { 'type': 'object', 'properties': { @@ -414,15 +414,19 @@ class LimitOffsetPagination(BasePagination): 'type': 'string', 'nullable': True, 'format': 'uri', - 'example': 'http://api.example.org/accounts/?{offset_param}=400&{limit_param}=100'.format( - offset_param=self.offset_query_param, limit_param=self.limit_query_param), + 'example': '{protocol}://{domain}{url}?{offset_param}=400&{limit_param}=100'.format( + offset_param=self.offset_query_param, limit_param=self.limit_query_param, + protocol=protocol, domain=domain, url=url + ), }, 'previous': { 'type': 'string', 'nullable': True, 'format': 'uri', - 'example': 'http://api.example.org/accounts/?{offset_param}=200&{limit_param}=100'.format( - offset_param=self.offset_query_param, limit_param=self.limit_query_param), + 'example': '{protocol}://{domain}{url}?{offset_param}=200&{limit_param}=100'.format( + offset_param=self.offset_query_param, limit_param=self.limit_query_param, + protocol=protocol, domain=domain, url=url + ), }, 'results': schema, }, @@ -898,7 +902,7 @@ class CursorPagination(BasePagination): ('results', data) ])) - def get_paginated_response_schema(self, schema): + def get_paginated_response_schema(self, schema, url='/accounts/', domain='api.example.org', protocol='http'): return { 'type': 'object', 'properties': { diff --git a/rest_framework/schemas/openapi.py b/rest_framework/schemas/openapi.py index 5e9d59f8b..809245041 100644 --- a/rest_framework/schemas/openapi.py +++ b/rest_framework/schemas/openapi.py @@ -118,7 +118,8 @@ class SchemaGenerator(BaseSchemaGenerator): class AutoSchema(ViewInspector): - def __init__(self, tags=None, operation_id_base=None, component_name=None): + def __init__(self, tags=None, operation_id_base=None, component_name=None, domain='api.example.org', + protocol='http'): """ :param operation_id_base: user-defined name in operationId. If empty, it will be deducted from the Model/Serializer/View name. :param component_name: user-defined component's name. If empty, it will be deducted from the Serializer's class name. @@ -128,6 +129,8 @@ class AutoSchema(ViewInspector): self._tags = tags self.operation_id_base = operation_id_base self.component_name = component_name + self.domain = domain + self.protocol = protocol super().__init__() request_media_types = [] @@ -683,7 +686,12 @@ class AutoSchema(ViewInspector): } paginator = self.get_paginator() if paginator: - response_schema = paginator.get_paginated_response_schema(response_schema) + response_schema = paginator.get_paginated_response_schema( + response_schema, + url=path, + domain=self.get_schema_domain(), + protocol=self.get_schema_protocol() + ) else: response_schema = item_schema status_code = '201' if method == 'POST' else '200' @@ -713,6 +721,12 @@ class AutoSchema(ViewInspector): return [path.split('/')[0].replace('_', '-')] + def get_schema_domain(self): + return self.domain + + def get_schema_protocol(self): + return self.protocol + def _get_path_parameters(self, path, method): warnings.warn( "Method `_get_path_parameters()` has been renamed to `get_path_parameters()`. " diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py index aef20670e..9e6e9521b 100644 --- a/tests/schemas/test_openapi.py +++ b/tests/schemas/test_openapi.py @@ -405,26 +405,22 @@ class TestOperationIntrospection(TestCase): path = '/' method = 'GET' - class Pagination(pagination.BasePagination): - def get_paginated_response_schema(self, schema): - return { - 'type': 'object', - 'item': schema, - } - class ItemSerializer(serializers.Serializer): text = serializers.CharField() class View(generics.GenericAPIView): serializer_class = ItemSerializer - pagination_class = Pagination + pagination_class = pagination.PageNumberPagination view = create_view( View, method, create_request(path), ) - inspector = AutoSchema() + inspector = AutoSchema( + domain='www.django-rest-framework.org', + protocol='https' + ) inspector.view = view responses = inspector.get_responses(path, method) @@ -435,10 +431,25 @@ class TestOperationIntrospection(TestCase): 'application/json': { 'schema': { 'type': 'object', - 'item': { - 'type': 'array', - 'items': { - '$ref': '#/components/schemas/Item' + 'properties': { + 'next': { + 'example': 'https://www.django-rest-framework.org/?page=4', + 'format': 'uri', + 'nullable': True, + 'type': 'string' + }, + 'previous': { + 'example': 'https://www.django-rest-framework.org/?page=2', + 'format': 'uri', + 'nullable': True, + 'type': 'string' + }, + 'count': {'example': 123, 'type': 'integer'}, + 'results': { + 'type': 'array', + 'items': { + '$ref': '#/components/schemas/Item' + }, }, }, }, @@ -583,7 +594,7 @@ class TestOperationIntrospection(TestCase): method = 'GET' class Pagination(pagination.BasePagination): - def get_paginated_response_schema(self, schema): + def get_paginated_response_schema(self, schema, url='/accounts/', domain='api.example.org', protocol='http'): return { 'type': 'object', 'item': schema,